C# 使用BinaryFormatter追加到文件
我正在使用这个代码C# 使用BinaryFormatter追加到文件,c#,serialization,binaryfiles,C#,Serialization,Binaryfiles,我正在使用这个代码 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 bF
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();
}
}
for(int i=0;i<3;++i)
{
List tl=新列表();
tl.Add(5);
tl.Add(4);
使用(var fileStream=newfilestream(@“C:\file.dat”,FileMode.Append))
{
var bFormatter=new BinaryFormatter();
序列化(fileStream,tl);
//fileStream.Close();
}
var list=新列表();
使用(var fileStream=newfilestream(@“C:\file.dat”,FileMode.Open))
{
var bFormatter=new BinaryFormatter();
//while(fileStream.Position!=fileStream.Length)
//{
//添加((int)bFormatter.Deserialize(fileStream));
//}
list=(list)bFormatter.反序列化(fileStream);
//fileStream.Close();
}
}
我预计.dat文件将被删除
54544
但它只是
5.4
此代码还返回
5.4
List tl=newlist();
tl.Add(5);
tl.Add(4);
使用(var fileStream=newfilestream(@“C:\file.dat”,FileMode.Append))
{
var bFormatter=new BinaryFormatter();
序列化(fileStream,tl);
}
tl.Clear();
tl.Add(3);
tl.Add(2);
使用(var fileStream=newfilestream(@“C:\file.dat”,FileMode.Append))
{
var bFormatter=new BinaryFormatter();
序列化(fileStream,tl);
}
var list=新列表();
使用(var fileStream=newfilestream(@“C:\file.dat”,FileMode.Open))
{
var bFormatter=new BinaryFormatter();
list=(list)bFormatter.反序列化(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);
}
}
var list=newlist();
使用(var fileStream=newfilestream(@“C:\file.dat”,FileMode.Open))
{
var bFormatter=new BinaryFormatter();
while(fileStream.Position!=fileStream.Length)
{
var t=(List)(bFormatter.Deserialize(fileStream));
列表。添加范围(t);
}
}
您正在添加三个整数列表,一个接一个,并且只回读第一个整数。我认为您的意图可能是附加到(单个)现有列表中,在这种情况下,您必须
BinaryFormatter
未列为可追加。实际上,在到达EOF(并手动合并)之前,通常可以多次进行反序列化,但是:还有其他序列化程序是显式设计为可追加的。例如,协议缓冲区是一种可追加的格式:串联与合并相同。进一步:如果外部元素是一个列表,那么添加到文件与添加到composes列表是相同的
使用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);
}
}
for(int i=0;i<3;++i)
{
List tl=新列表();
tl.Add(5);
tl.Add(4);
使用(var fileStream=newfilestream(@“C:\file.dat”,FileMode.Append))
{
Serializer.Serialize(fileStream,tl);
}
使用(var fileStream=newfilestream(@“C:\file.dat”,FileMode.Open))
{
list=序列化程序。反序列化(fileStream);
}
}
在每次循环迭代结束时,
list
(即反序列化后)有2个、4个、6个元素。如Marc Gravel所述,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);
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
使用System.Runtime.Serialization.Formatters.Binary;
班级计划
{
常量字符串文件=@“C:\temp\file.dat”;
静态void Main()
{
对于(int i=0;i<3;++i)
{
List tl=新列表();
tl.Add(5);
tl.Add(4);
追加磁盘(tl);
}
var list=ReadFromDisk();
foreach(列表中的变量项)
{
控制台。写入(项);
}
}
私有静态void AppendToDisk(IEnumerable集合)
{
var existing=ReadFromDisk().ToList();
现有.AddRange(集合);
PersistToDisk(现有);
}
私有静态void persistDisk(ICollection值)
{
如果(!File.Exists(File))
{
使用(File.Create(File)){};
}
var bFormatter=new BinaryFormatter();
使用(var stream=File.OpenWrite(File))
{
序列化(流、值);
}
}
私有静态ICollection ReadFromDisk()
{
如果(!File.Exists(File))返回Enumerable.Empty().ToArray();
var bFormatter=new BinaryFormatter();
使用(var stream=File.OpenRead(File))
{
返回(ICollection)bFormatter.反序列化(流);
}
}
}
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);
}
}
}