我正在使用此代码
for (int i = 0; i < 3; ++i)
{
List<int> tl = new List<int>();
tl.Add(5);
tl.Add(4);
using (var fileStream = new FileStream(@"C:\file.dat", FileMode.Append))
{
var bFormatter = new BinaryFormatter();
bFormatter.Serialize(fileStream, tl);
//fileStream.Close();
}
var list = new List<int>();
using (var fileStream = new FileStream(@"C:\file.dat", FileMode.Open))
{
var bFormatter = new BinaryFormatter();
//while (fileStream.Position != fileStream.Length)
//{
// list.Add((int)bFormatter.Deserialize(fileStream));
//}
list = (List<int>)bFormatter.Deserialize(fileStream);
//fileStream.Close();
}
}
我希望.dat文件是
5 4 5 4 5 4
但它只是
5 4
此代码也返回
5 4
List<int> tl = new List<int>();
tl.Add(5);
tl.Add(4);
using (var fileStream = new FileStream(@"C:\file.dat", FileMode.Append))
{
var bFormatter = new BinaryFormatter();
bFormatter.Serialize(fileStream, tl);
}
tl.Clear();
tl.Add(3);
tl.Add(2);
using (var fileStream = new FileStream(@"C:\file.dat", FileMode.Append))
{
var bFormatter = new BinaryFormatter();
bFormatter.Serialize(fileStream, tl);
}
var list = new List<int>();
using (var fileStream = new FileStream(@"C:\file.dat", FileMode.Open))
{
var bFormatter = new BinaryFormatter();
list = (List<int>)bFormatter.Deserialize(fileStream);
}
它看起来只反序列化了附加的第一部分。
为什么数据不附加?
更新 所以解决方案是:
var list = new List<int>();
using (var fileStream = new FileStream(@"C:\file.dat", FileMode.Open))
{
var bFormatter = new BinaryFormatter();
while (fileStream.Position != fileStream.Length)
{
var t = (List<int>)(bFormatter.Deserialize(fileStream));
list.AddRange(t);
}
}
答案 0 :(得分:3)
您要添加三个整数列表,一个接一个,只读取第一个。我认为你的意图可能是附加到(单个)现有列表,在这种情况下你必须
答案 1 :(得分:1)
BinaryFormatter
未列为可附加内容。实际上,你可以通常多次反序列化,直到你进入EOF(并手动合并),但是:还有其他序列化工具 明确设计为是可以附加的。例如,协议缓冲区是可附加格式:连接与合并相同。此外:如果外部元素是列表,则附加到文件与添加到撰写列表相同。
使用protobuf-net,这只是:
for (int i = 0; i < 3; ++i)
{
List<int> tl = new List<int>();
tl.Add(5);
tl.Add(4);
using (var fileStream = new FileStream(@"C:\file.dat", FileMode.Append))
{
Serializer.Serialize(fileStream, tl);
}
using (var fileStream = new FileStream(@"C:\file.dat", FileMode.Open))
{
list = Serializer.Deserialize<List<int>>(fileStream);
}
}
在每次循环迭代结束时,list
(即反序列化后)有2,然后是4,然后是6个元素。
答案 2 :(得分:1)
正如Marc Gravell所说,BinaryFormatter
不可附加,这意味着您每次需要修改文件时都需要重新编译。
示例:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
class Program
{
const string file = @"C:\temp\file.dat";
static void Main()
{
for (int i = 0; i < 3; ++i)
{
List<int> tl = new List<int>();
tl.Add(5);
tl.Add(4);
AppendToDisk(tl);
}
var list = ReadFromDisk<int>();
foreach (var item in list)
{
Console.Write(item);
}
}
private static void AppendToDisk<T>(IEnumerable<T> collection)
{
var existing = ReadFromDisk<T>().ToList();
existing.AddRange(collection);
PersistToDisk(existing);
}
private static void PersistToDisk<T>(ICollection<T> value)
{
if (!File.Exists(file))
{
using (File.Create(file)) { };
}
var bFormatter = new BinaryFormatter();
using (var stream = File.OpenWrite(file))
{
bFormatter.Serialize(stream, value);
}
}
private static ICollection<T> ReadFromDisk<T>()
{
if (!File.Exists(file)) return Enumerable.Empty<T>().ToArray();
var bFormatter = new BinaryFormatter();
using (var stream = File.OpenRead(file))
{
return (ICollection<T>)bFormatter.Deserialize(stream);
}
}
}