我的代码是这样的:
[Serializable]
[StructLayout(LayoutKind.Sequential,Pack=1)]
struct Foo
{
public byte Bar;
public Foo(byte b){Bar=b;}
}
public static void Main (string[] args)
{
Foo[] arr = new Foo[1000];
for (int i = 0; i < 1000; i++) {
arr[i]=new Foo(42);
}
var fmt = new BinaryFormatter();
using(FileStream f= File.Create("test.bin")){
fmt.Serialize(f,arr);
}
Console.WriteLine (new FileInfo("test.bin").Length);
}
Run Code Online (Sandbox Code Playgroud)
Foo结构会占用这么多字节?每个结构开销的9个字节到底是多少?PS:我正在为中文字符编写一个查找库(它是关于大约70,000个字符的信息),db4o或其他可嵌入数据库(如sqlite)有点膨胀.我认为以纯字符串格式存储所有信息,这是最友好的,但不太灵活.我想将信息保存在列表中并将它们作为二进制序列化存储到存档中,我选择了DotNetZip进行存档.但序列化开销是一个意想不到的障碍.一个更好的序列化解决方案将是好的,否则我将以纯字符串格式保存信息并通过硬编码解析它.
Pet*_*ene 14
Foo结构不是那么"大",而是你所观察到的是二进制序列化格式本身的开销.这种格式包含一个标题,描述对象图形的信息,描述数组的信息,描述类型和汇编信息的字符串等.也就是说它包含足够的信息,BinaryFormatter.Deserialize可以像往常一样返回一个Foo数组. .
有关详细信息,请参阅以下详细说明格式的规范:http://msdn.microsoft.com/en-us/library/cc236844(PROT.10).aspx
根据您更新的问题进行修改:
如果您希望简单地将结构的内容写入流中,则可以在不安全的上下文中轻松完成(此代码基于您的示例).
用一个小数组写出每个Foo:
unsafe
{
byte[] data = new byte[sizeof(Foo)];
fixed (Foo* ptr = arr)
{
for (int i = 0; i < arr.Length; ++i)
{
Marshal.Copy((IntPtr)ptr + i, data, 0, data.Length);
f.Write(data, 0, data.Length);
}
}
}Run Code Online (Sandbox Code Playgroud)
或者使用一个足够大的数组来写出所有Foos:
unsafe
{
byte[] data = new byte[sizeof(Foo) * arr.Length];
fixed (Foo* ptr = arr)
{
Marshal.Copy((IntPtr)ptr, data, 0, data.Length);
f.Write(data, 0, data.Length);
}
}Run Code Online (Sandbox Code Playgroud)
根据您的示例,这将写出1000个字节,每个值为42.
但是,这种方法有一些缺点.如果您熟悉用C语言编写结构,其中一些应该是显而易见的:
BinaryFormatter为您解决了这些问题,但却产生了您在执行此操作时所观察到的空间开销.它旨在以安全的方式在机器之间交换数据.如果您不想使用BinaryFormatter,那么您需要定义自己的文件格式并自行处理这种格式的读写,或使用最适合您需求的第三方序列化库(我将离开研究)这些图书馆由您决定).