件,后缀 .ser没有特别的意思,这是约定俗成的表示这是一个串行化数据文件。从标记3a至3h,表示一个对象被串行化至文件中。在字符串的情况下,每个字符都被写入;在数组的情况下,所有元素都被写入;在日期时间的情况下,类型中包含的所有数据及有关依赖项都被写入;在为原始类型值的情况下,它们先被装箱,然后对应的对象被写入。上述动作中,串行化只需要接收一个Object^类型参数的对象即可。
通过调用Deserialize函数,可取回串行化后的数据,如标记6a中所示;因为此函数返回一个Object^类型的值,所以需要把它转换为相应的值。
程序的输出如插1所示:
插1:例1中串行化、反串行化的输出
String >Hello<
newIntArray
10 20 30
newFloatArray:
1.2 2.4
3.5 6.8
8.4 9.7
bool >True<
newDT >9/29/2005 3:25:44 PM<
int >1000<
wchar_t >X<
float >1.23456<
串行化包含引用的对象
在前一个例子中,我们对相关类型进行了简单的读写。那么,如果一个对象中包含了其他对象的句柄呢?试想有一个超过两万字的字典,存储在一个能通过键值索引的集合中,而在标准
模板库中,就提供了一个这样的集合--哈希表(Hashtable),如例2中所示:
例2:
using namespace System;
using namespace System::IO;
using namespace System::Collections;
using namespace System::Runtime::Serialization::Formatters::Binary;
int main()
{
/*1*/ Hashtable^ dictionary = gcnew Hashtable(21000);
StreamReader^ inStream = File::OpenText("dictionary.txt"); //打开字典文件
String^ str;
while ((str = inStream->ReadLine()) != nullptr)
{
/*2*/ dictionary->Add(str, nullptr);
}
inStream->Close();
/*3*/ Console::WriteLine("Dictionary contains {0} entries", dictionary->Count);
BinaryFormatter^ formatter = gcnew BinaryFormatter();
Stream^ file = File::Open("dictionary.ser", FileMode::Create);
/*4*/ formatter->Serialize(file, dictionary);
file->Close();
}
在标记1中,我们先分配了一个初始化为21000个条目的哈希表(这样做只是为了加快处理速度,在条目相加时不需要重新进行分配),接着从一个文本文件中,一次一行地读入字,并将其添加到标记2的哈希表中。请注意,在定义中,哈希表的每个条目都由(键/值)对组成。但在我们的
程序中,键也是值,所以在第二个参数中使用了nullprt。
哈希表中的键值必须是唯一的,而添加进来的任何类型的对象都必须重载System::对象名 GetHashCode函数--字符串也一样。
一旦文件中所有的字被读取并添加到哈希表中,就可通过一个简单的Serialize调用,把哈希表写到磁盘上,如标记4所示。在例3中,我们读入这个字典,并在其中查找用户提供的字,插2是对应的输出。
例3:
using namespace System;
using namespace System::IO;
using namespace System::Collections;
using namespace System::Runtime::Serialization::Formatters::Binary;
int main()
{
BinaryFormatter^ formatter = gcnew BinaryFormatter;
Stream^ file = File::Open("dictionary.ser", FileMode::Open);
/*1*/ Hashtable^ dictionary = static_cast<Hashtable^>(formatter->Deserialize(file));
file->Close();
/*2*/ Console::WriteLine("Dictionary contains {0} entries", dictionary->Count);
String^ word;
while (true)
{
Console::Write("Enter a word: ");
word = Console::ReadLine();
if (word == nullptr)
{
break;
}