【问题标题】:Using BinaryFormatter in a sequential manner in C#在 C# 中以顺序方式使用 BinaryFormatter
【发布时间】:2012-01-24 13:59:47
【问题描述】:

注意:我知道在大文件中使用 BinaryFormatter 的缺点。但这是我朋友的作业:

(.Net Framework 4)我创建了一个简单的Person 类,它应该被序列化并写入二进制文件。

  • 对于插入,操作如下:打开/创建文件,查找文件末尾,添加序列化的Person 对象,关闭文件。我不想序列化一个List<Person> 并一次写完。
  • For Reading(基于index参数):打开文件,寻找index位置(基于对象长度),反序列化index处的对象,返回对象。
  • 删除:就像读取index位置的记录一样,到索引位置,删除它,保存文件。

我不确定使用BinaryFormatter 是否是正确的方法。例如对于插入,我见过这样的例子:

FileStream fs = new FileStream(_fileName, FileMode.Open);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, person);
fs.Close();  

这会导致文件中的所有数据丢失并且文件将只包含person 对象。如何在文件中按顺序对对象进行二进制读/写/删除?我对插入的猜测是使用另一个流,将对象序列化到该流中。将流写入字节数组并使用该字节数组写入我的主文件流的末尾。但我想不出适合插入/删除操作的方法。有什么比BinaryFormatter 更适合使用的方法吗?

注意:为了更清楚,他告诉我老师希望他们计算每次操作的时间。
谢谢。

【问题讨论】:

  • append 通常是可能的(虽然 BF 不是我在这里的首选);但是 deleteinsert 要求您移动所有后续数据...这通常是一个问题
  • @MarcGravell:好吧...我似乎不知道如何一次只读取一条记录。
  • 那么,当您尝试当前阅读时会发生什么?就个人而言,我会在这里使用记录为可附加的格式......几乎没有关于 BF 将做什么的记录 - 实现细节是私有的。对于 BF,如有必要,您可以编写一个子类 Stream 实现并限制长度。这不是我会怎么做的! (作为记录,我会使用带有[Serialize|Deserialize]WithLengthPrefix的protobuf-net,它是a:在开放规范中记录为可附加,b:自我限制(它不会过度阅读)。不确定是否有帮助不过,你的朋友。
  • @MarcGravell:谢谢,我和你在一起protobuf-net。可惜我不得不使用BinaryFormatter...

标签: c# serialization deserialization binaryfiles binary-data


【解决方案1】:

你的代码是正确的,除了第一行:

FileStream fs = new FileStream(_fileName, FileMode.Append)

这将允许formatter.Serialize(fs,person) 将自己附加到文件中。

var listFromFile = new List<Person>();    

using (var fileStream = new FileStream("C:\file.dat", FileMode.Open))
{
    var bFormatter = new BinaryFormatter();
    while (fileStream.Position != fileStream.Length)
    {
         list.Add((Person)bFormatter.Deserialize(fileStream));
    }
}

就插入而言,这应该可以从文件中获取列表...您可能必须在读取对象后重写对象并插入新对象,与删除相同。

【讨论】:

  • @Kamyar 编辑以展示您如何阅读,阅读后删除应该很简单
猜你喜欢
  • 2018-06-11
  • 2010-12-10
  • 1970-01-01
  • 1970-01-01
  • 2010-11-03
  • 2019-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多