为什么二进制文件与文本相比变化很大?

时间:2014-04-02 12:36:55

标签: c# serialization binary

我一直在TEXT文件中保留一大组数据作为TEXT记录:

yyyyMMddTHHmmssfff doube1 double2

但是当我阅读它时,我需要解析每个DateTime。数百万条记录的速度非常慢。

所以,现在我正在尝试将它作为一个二进制文件,我通过对我的类进行血清化来创建。

这样我就不需要解析DateTime了。

    class MyRecord 
    {
           DateTime DT;
           double Price1;
           double Price2;
    }

            public byte[] SerializeToByteArray()
            {
                var bf = new BinaryFormatter();
                using (var ms = new MemoryStream())
                {
                    bf.Serialize(ms, this);
                    return ms.ToArray();
                }
            }

    MyRecord mr = new MyRecord();

    outBin = new BinaryWriter(File.Create(binFileName, 2048, FileOptions.None));

   for (AllRecords) //Pseudo
    {
        mr = new MyRecord(); //Pseudo
        outBin.Write(mr.SerializeToByteArray());
    }

生成的二进制文件平均是TEXT文件大小的3倍。

这是预期的吗?

编辑1

我正在探索使用Protbuf来帮助我:

我希望使用USING来适应我现有的结构。

   private void DisplayBtn_Click(object sender, EventArgs e)
    {
        string fileName = dbDirectory + @"\nAD20120101.dat";

        FileStream fs = File.OpenRead(fileName);

        MyRecord tr;
        while (fs.CanRead)
        {

            tr = Serializer.Deserialize<MyRecord>(fs);

            Console.WriteLine("> "+ tr.ToString());

        }

    }

但是在第一次记录tr之后 - 充满了零。

3 个答案:

答案 0 :(得分:1)

您的存档可能会在每个记录中序列化类型信息的开销很大。

相反,让整个集合可序列化(如果它还没有)并一次性序列化。

答案 1 :(得分:0)

您不是存储DateTime的简单二进制版本,而是存储表示这些版本的对象。这比将日期存储为文本要大得多。

如果您创建了一个类

class MyRecords
{
    DateTime[] DT;
    double[] Price1;
    double[] Price2;
}

并序列化它,它应该小得多。

此外,我猜DateTime仍然需要大量空间,因此您可以将DateTime转换为整数Unix时间戳并存储它。

答案 2 :(得分:0)

如OP所要求的那样。

输出不是二进制文件,它是实例的二进制序列化加上BinaryFormatter的开销,以允许稍后进行反序列化,因此您获得的文件大于预期的3倍 如果您需要智能序列化解决方案,可以查看ProtoBuf-net https://code.google.com/p/protobuf-net/

here您可以找到解释如何实现此目标的链接

 [ProtoContract]
Public class MyRecord 
    {   [ProtoMember(1)]
           DateTime DT;
         [ProtoMember(2)]
           double Price1;
          [ProtoMember(3)]
           double Price2;
    }