【问题标题】:Modify data via StreamWriter or file writes?通过 StreamWriter 或文件写入修改数据?
【发布时间】:2011-08-29 22:15:17
【问题描述】:

我需要创建二进制数据文件。它不能一次创建,我需要序列化一些数据,然后返回并在标头中写入偏移量。文件将舒适地放入内存(几兆字节)。我可以使用BinaryWriter 并使用writer.Seek(x, SeekOrigin.Begin) 返回写入偏移量吗?或者也许写入文件(然后修改它)有什么优势?或者也许没有真正的区别?

【问题讨论】:

  • 你需要做多少寻找?我想如果您用于编写器的底层流是 MemoryStream,而不是 FileStream,它会更快。这样可以减少磁盘访问,并且可以一次将完成的流写入磁盘。

标签: c# .net stream streamwriter binarywriter


【解决方案1】:

您应该创建一个打包结构来表示文件头,而不是文件中的偏移量。填写结构并写在文件的开头。一口气读懂结构也会更容易。

【讨论】:

  • 在其余数据被序列化(写入文件/流写入器)之前,我不知道要在标头中写入的值。如果我们将“写入偏移量”更改为“写入填充的标头结构”,问题仍然存在。
  • 将空结构写入文件。然后将记录偏移量的所有“东西”写入结构中。然后重写结构......(当然在偏移量为零)。
【解决方案2】:

我想我理解你的问题。您正在序列化程序其他部分的对象,并且在您要求序列化它之前您不知道每个块有多大..并且您不想一次序列化所有这些对象,因为这可能是一个很多内存。

所以你想在文件的前面留出一些空间,将二进制数据分块写入,同时记录每个块的大小,然后返回并写入标题以指示每个块的开始和停止位置。

您要求的解决方案似乎是合理的,但我相信如果您回溯到标头位置,BinaryWriter 会覆盖,因此您需要预先写一个空字节垫,以便为自己留出空间来写标头 - http://msdn.microsoft.com/en-us/library/system.io.binarywriter.seek.aspx#Y640

现在的问题是,你的标题要多大?你写了多少个空字节?可能取决于您必须序列化的对象数量。听起来你现在遇到了和以前一样的问题。

相反,我会按顺序打包您的数据,例如:

| --------- Chunk 1 ----------|--------- Chunk 2 -----------|
| length | name | ... | bytes | length | name | ... | bytes |

长度参数编码该块的总长度,接下来您拥有每个块的任何属性,然后是被序列化的实际对象的原始字节。

【讨论】:

    猜你喜欢
    • 2020-01-08
    • 2011-10-29
    • 2017-11-20
    • 2012-02-22
    • 2014-02-22
    • 2018-08-24
    • 1970-01-01
    • 1970-01-01
    • 2013-01-16
    相关资源
    最近更新 更多