在 C# 中从二进制文件读取数组内容/向二进制文件写入数组内容的最佳方法是什么?
我想读取和写入大型原始卷文件的内容(例如 MRI 扫描)。这些文件只是一个序列,例如 32 x 32 x 32 浮点数,因此它们可以很好地映射到一维数组。我希望能够将二进制卷文件的内容读入一维数组,例如 float 或 ushort(取决于二进制文件的数据类型),并类似地将数组导出回原始卷文件。
使用 C# 执行此操作的最佳方法是什么?使用 BinaryReader/BinaryWriter 一次读取/写入 1 个元素?使用 FileStream.Read 将它们分段读取到字节数组中,然后在数组之间执行 System.Buffer.BlockCopy?编写我自己的读者/作家?
编辑:似乎无法与 > 一起使用2GB 阵列,但问题仍然是较小的阵列(大约 256 MB 左右)
I would like to read and write the contents of large, raw volume files (e.g. MRI scans). These files are just a sequence of e.g. 32 x 32 x 32 floats so they map well to 1D arrays. I would like to be able to read the contents of the binary volume files into 1D arrays of e.g. float or ushort (depending on the data type of the binary files) and similarly export the arrays back out to the raw volume files.
What's the best way to do this with C#? Read/Write them 1 element at a time with BinaryReader/BinaryWriter? Read them piece-wise into byte arrays with FileStream.Read and then do a System.Buffer.BlockCopy between arrays? Write my own Reader/Writer?
EDIT: It seems it's not possible to work with > 2GB arrays, but the question still stands for smaller arrays (around 256 MB or so)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您不会获得包含超过 2GB 数据的数组。据我所知,每个对象的 CLR 限制为 1GB。 64 位上的 .NET 4 可能已取消该功能,但我还没有听说过。
编辑:根据 本文 限制是2GB,而不是 1GB - 但您仍然无法管理超过 2GB 的内存。
您真的必须一次性将所有数据存入内存吗?你能一次处理其中的大部分内容吗?
编辑:好的,现在只是从文件读入浮点数组?读取块可能是最简单的(使用 BinaryReader.Read(byte[], int, int) 或 BinaryReader.ReadBytes(int) ),然后使用 Buffer .BlockCopy 有效地从字节转换为浮点数等。但是请注意,这将是字节序敏感的。如果您想更稳健地进行转换(以便稍后可以更改字节序,或在大字节序平台上运行),您可能需要重复调用
ReadFloat()
。您对这部分代码确实存在性能问题的确信程度如何?值得做最简单的事情,然后对其进行分析,首先......
You're not going to get arrays with more than 2GB data. From what I remember, there's a CLR limit of 1GB per object. It's possible that's been lifted for .NET 4 on 64-bit, but I haven't heard about it.
EDIT: According to this article the limit is 2GB, not 1GB - but you still won't manage more than 2GB.
Do you really have to have all the data in memory at one time? Can you work on chunks of it at a time?
EDIT: Okay, so it's now just about reading from a file into a float array? It's probably simplest to read chunks (either using
BinaryReader.Read(byte[], int, int)
orBinaryReader.ReadBytes(int)
) and then useBuffer.BlockCopy
to efficiently convert from bytes to floats etc. Note that this will be endian-sensitive, however. If you want to convert more robustly (so that you can change endianness later, or run on a big-endian platform) you'd probably want to callReadFloat()
repeatedly.How convinced are you that you actually have a performance issue in this area of the code? It's worth doing the simplest thing that will work and then profiling it, to start with...