c# - 使用 BinaryReader 逐行读取

标签 c# .net binaryreader

我正在使用以下代码序列化数据表中的数据。

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

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

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) -> 读取的值应该是多少?我事先不知道。我需要阅读整行并转换为字典。我用于转换回来的方法是:

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发生。同样代表反序列化。这就是为什么我希望它部分序列化/反序列化。

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

最佳答案

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

读取时,每次迭代先读取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);
    }
}                

关于c# - 使用 BinaryReader 逐行读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42657779/

相关文章:

c# - 如何在 C# 中使用 BinaryReader 一次读取二进制数据?

c# - 通过 BinaryReader 从 NetStream 读取的正确方法是什么?

c# - Entity Framework 上的多个 .Where() 子句可查询

javascript - 将 3 个文本框值从 ASPX 传递给 JavaScript 函数

c# - 定义此通用接口(interface)以便编译的最干净的方法是什么?

c# - 如何防止将字符串 (a-z) 粘贴到 C# 中的文本框(仅限数字)

c# - .net WinDbg 强句柄泄漏

c# - 用于在C#中检查有效属性名称的正则表达式

c# - 如何在 MVVM WPF 应用程序中控制列表框的滚动位置

C# BinaryReader.ReadChar 读取 NetworkStream 时抛出 "System.ArgumentException: The output char buffer is too small"