【问题标题】:Difficulty reading large file into byte array难以将大文件读入字节数组
【发布时间】:2017-11-13 11:55:58
【问题描述】:

我有一个非常大的 BMP 文件,我必须一次全部读取,因为在将它写入临时文件时我需要反转字节。此 BMP 为 1.28GB,我收到“内存不足”错误。我无法完全读取它(使用 ReadAllBytes)或使用缓冲区到二进制数组,因为我无法初始化该大小的数组。我也无法使用缓冲区将其读入列表(然后我可以使用 Reverse()),因为中途内存不足。

所以基本上问题是,我如何向后读取一个非常大的文件(即,从 LastByte 开始并在 FirstByte 结束)然后将其写入磁盘?

奖励:将反转的文件写入磁盘时,不要写入最后 54 个字节。

【问题讨论】:

  • 编辑问题以包含您正在使用的 .NET 框架版本会有所帮助,因为从版本 4 开始,您可以通过托管代码访问内存映射文件。

标签: c# filestream large-files


【解决方案1】:

使用StreamReader 对象,您可以将Seek(放置“光标”)到任何特定字节,这样您就可以使用它来反向遍历整个文件的内容。

例子:

const int bufferSize = 1024;
string fileName = 'yourfile.txt';

StreamReader myStream = new StreamReader(fileName);
myStream.BaseStream.Seek(bufferSize, SeekOrigin.End);

char[] bytes = new char[bufferSize];
while(myStream.BaseStream.Position > 0)
{
    bytes.Initialize();
    myStream.BaseStream.Seek(bufferSize, SeekOrigin.Current);
    int bytesRead = myStream.Read(bytes, 0, bufferSize);
}

【讨论】:

  • 谢谢!而不是 SeekOrigin.Current,我只是使用 Position 选项遍历文件,向前读取我需要的字节数,然后在使用 Filestream Append 将其写入磁盘之前反转缓冲区。效果很好!
【解决方案2】:

您通常无法在 .NET 中处理如此大的文件,因为 CLR 应用程序和其中的集合的隐含内存限制既不适用于 32 也不适用于 64 平台。

为此,您可以使用Memory Mapped File,直接从磁盘读取文件,而无需将其加载到内存中。一次创建的内存映射将读取指针移动到文件末尾并向后读取。

希望这会有所帮助。

【讨论】:

    【解决方案3】:

    您可以使用内存映射文件。

    http://msdn.microsoft.com/en-us/library/vstudio/dd997372%28v=vs.100%29.aspx

    另外,您可以使用 FileStream 并通过 stream.Seek(xxx, SeekOrigin.Begin)(相对位置)或 Position 属性(绝对位置)在必要位置上定位。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-08
      • 1970-01-01
      相关资源
      最近更新 更多