我使用以下代码从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发生的话。同样代表反序列化。这就是我希望它部分序列化/反序列化的原因。
尝试了一切,到处搜寻。感谢您帮助解决这个问题。
答案 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);
}
}