逐行读取BinaryReader

时间:2017-03-07 20:32:15

标签: c# .net binaryreader

我使用以下代码从dataTable序列化数据。

var rows = new List<Dictionary<string, object[]>>();

我正在填充DataTable中的行并将它们放在Dictionary中。不要问为什么:)

using(var fileStream = new FileStream(@"D:\temp.bin", FileMode.Create, FileAccess.Write, FileShare.None))
using(var bw = new BinaryWriter(fileStream))
{
    foreach(Dictionary<string, object[]> row in rows)
    {
        byte[] bytes = ObjectToByteArray(row);
        bw.Write(bytes);
    }
}

使用以下方法:

private static byte[] ObjectToByteArray(Dictionary<string, object[]> rows)
{
    var bf = new BinaryFormatter();
    using(var ms = new MemoryStream())
    {
        bf.Serialize(ms, rows);
        return ms.ToArray();
    }
}

我想要做的是逐行反序列化,如果可以使用BinaryReader。问题是我只能阅读第一行。

我想要达到的目标是:

using(BinaryReader reader = new BinaryReader(File.Open(@"D:\temp.bin", FileMode.Open)))
{
    int pos = 0;
    int length = (int)reader.BaseStream.Length;
    while(pos < length)
    {
        byte[] v = reader.ReadBytes(pos);
        Dictionary<string, object[]> row = FromByteArray(v);
        // Advance our position variable.
        pos += row.Count;
    }
}

最大的问题是reader.ReadBytes(XXX) - &gt;应该读什么价值?我事先并不知道。我需要阅读整行并转换为Dictionary。我用于转换的方法是:

public static Dictionary<string, object[]> FromByteArray(byte[] data)
{
    BinaryFormatter bf = new BinaryFormatter();
    using(MemoryStream ms = new MemoryStream(data))
    {
        object obj = bf.Deserialize(ms);
        return (Dictionary<string, object[]>)obj;
    }
}

正如我所说的FromByteArray在第一行工作正常,我找不到任何方法来阅读下一行。

当我使用BinarryFormatter序列化完整文件时,如果文件不是那么大,它就会通过。如果是OOM发生的话。同样代表反序列化。这就是我希望它部分序列化/反序列化的原因。

尝试了一切,到处搜寻。感谢您帮助解决这个问题。

1 个答案:

答案 0 :(得分:5)

对于每次迭代,在文件中还保存以下序列化对象的长度。

读取时,每次迭代首先读取4个字节(reader.ReadInt32)以获取此值并读取这么多字节以反序列化。

我认为它应该是这样的:

using(var fileStream = new FileStream(@"D:\temp.bin", FileMode.Create, FileAccess.Write, FileShare.None))
{
    using(var bw = new BinaryWriter(fileStream))
    {
        foreach(Dictionary<string, object[]> row in rows)
        {
            byte[] bytes = ObjectToByteArray(row);
            bw.Write(bytes.Length);
            bw.Write(bytes);
        }
    }
}


using(BinaryReader reader = new BinaryReader(File.Open(@"D:\temp.bin", FileMode.Open)))
{
    int length = (int)reader.BaseStream.Length;
    while(reader.BaseStream.Position != length)
    {
        int bytesToRead = reader.ReadInt32();
        byte[] v = reader.ReadBytes(bytesToRead);
        Dictionary<string, object[]> row = FromByteArray(v);
    }
}