本栏文章均来自于互联网,版权归原作者和各发布网站所有,收集这些文章仅供学习参考之用。任何人都不能将这些文章用于商业或者其他目的。
串行化可使对象被转换为某种外部的形式,比如以文件存储的形式供程序使用,或通过程序间的通讯发送到另一个处理过程。转换为外部形式的过程称为"串行化",而逆过程称为"反串行化"。
简介
请看例1中的示例,其将多个对象类型的值写入到一个新的磁盘文件中,关闭文件,接着再把这些值重新读取到内存中。
例1:
using namespace System;
using namespace System::IO;
using namespace System::Runtime::Serialization::Formatters::Binary;
int main()
{
array
^ intArray = {10, 20, 30};
array^ floatArray = {
{1.2F, 2.4F},
{3.5F, 6.8F},
{8.4F, 9.7F}
};
DateTime dt = DateTime::Now;
Console::WriteLine("dt >{0}Serialize(file, "Hello");
/*3b*/ formatter->Serialize(file, intArray);
/*3c*/ formatter->Serialize(file, floatArray);
/*3d*/ formatter->Serialize(file, true);
/*3e*/ formatter->Serialize(file, dt);
/*3f*/ formatter->Serialize(file, 1000);
/*3g*/ formatter->Serialize(file, L'X');
/*3h*/ formatter->Serialize(file, 1.23456F);
/*4*/ file->Close();
//从文件中反串行化数据--即读取数据
/*5*/ file = File::Open("Sr01.ser", FileMode::Open);
/*6a*/ String^ s = static_cast(formatter->Deserialize(file));
Console::WriteLine("String >{0}^ newIntArray =
static_cast^>(formatter->Deserialize(file));
Console::WriteLine("newIntArray:");
for (int i = 0; i Length; ++i)
{
Console::Write(" {0}", newIntArray[i]);
}
Console::WriteLine();
/*6c*/ array^ newFloatArray =
static_cast^>(formatter->Deserialize(file));
Console::WriteLine("newFloatArray:");
for (int i = 0; i <3 j="0;" j="j" bool b="static_castbool">(formatter->Deserialize(file));
Console::WriteLine("bool >{0}(formatter->Deserialize(file));
Console::WriteLine("newDT >{0}(formatter->Deserialize(file));
Console::WriteLine("int >{0}(formatter->Deserialize(file));
Console::WriteLine("wchar_t >{0}(formatter->Deserialize(file));
Console::WriteLine("float >{0}Close();
}
在标记1中,我们定义了一个BinaryFormatter类型的变量,此种类型的任意对象都可以二进制的形式进行串行与反串行化。
在标记2中,用指定的名称创建了一个新的文件,后缀 .ser没有特别的意思,这是约定俗成的表示这是一个串行化数据文件。从标记3a至3h,表示一个对象被串行化至文件中。在字符串的情况下,每个字符都被写入;在数组的情况下,所有元素都被写入;在日期时间的情况下,类型中包含的所有数据及有关依赖项都被写入;在为原始类型值的情况下,它们先被装箱,然后对应的对象被写入。上述动作中,串行化只需要接收一个Object^类型参数的对象即可。
通过调用Deserialize函数,可取回串行化后的数据,如标记6a中所示;因为此函数返回一个Object^类型的值,所以需要把它转换为相应的值。程序的输出如插1所示:
插1:例1中串行化、反串行化的输出
String >HelloTrue9/29/2005 3:25:44 PM1000X1.23456ReadLine()) != 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(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;
}
/*3*/ Console::WriteLine("{0}{1} found", word, (dictionary->Contains(word) ? "" : " not"));
}
}
插2:使用反串行化进行字典查找
Dictionary contains 20159 entries
Enter a word: house
house found
Enter a word: houses
houses not found
Enter a word: brick
brick found
Enter a word: manly
manly not found
此处最重要的是,我们能在单个函数调用中,串行、反串行化任意大小、任意复杂性的对象。
处理多个句柄
当我们传递一个对象的句柄给Serialize时,似乎会在底层对对象进行一个复制,那么,实际情况真的是这样吗?假设我们把包含有多个句柄的一个对象写入到其他对象中,或者我们调用Serialize两次,每次都给它同一个对象的句柄呢?我们真的想得到同一对象的多个副本吗?在例4中演示了这个过程:
例4:
using namespace System;
using namespace System::IO;
using namespace System::Runtime::Serialization::Formatters::Binary;
/*1*/ [Serializable]
ref class Employee { /* ... */};
int main()
{
Employee^ emp1 = gcnew Employee();
Employee^ emp2 = gcnew Employee();
Employee^ emp3 = emp2;
/*2a*/ Console::WriteLine("emp1 == emp2 is {0}", (emp1 == emp2));
/*2b*/ Console::WriteLine("emp2 == emp3 is {0}", (emp2 == emp3));
/*2c*/ Console::WriteLine("emp1 == emp3 is {0}", (emp1 == emp3));
array
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/8383357/viewspace-919710/
,如需转载,请注明出处,否则将追究法律责任。