C#加载二进制文件

4
请告诉我以下最佳/快速方法:
1)将非常小的二进制文件加载到内存中。例如图标;
2)加载/读取大小为512Mb +的非常大的二进制文件。
3)当您不想考虑大小/速度但必须执行一项任务时,您的常见选择是什么:将所有字节读入内存?
谢谢!!!
P.S. 对于可能很简单的问题,我很抱歉。请不要关闭它;)
P.S.2. Java类似问题的镜像

1
您可能会对以下文章感兴趣:http://www.codeproject.com/KB/files/fastbinaryfileinput.aspx - Cody Gray
4个回答

5

1:对于非常小的文件,File.ReadAllBytes 可以胜任。

2:对于非常大的文件和使用 .net 4.0,您可以使用 MemoryMapped Files。

3:如果没有使用 .net 4.0,则读取数据块是一个不错的选择。


所有答案都有其有用之处。但对于大文件,我更喜欢使用内存映射文件——我的老朋友来自本地Windows API ;) - Edward83

5

1) 我会使用资源文件而不是存储很多独立的文件。

2) 你可能想要流式传输数据而不是一次性读取,这种情况下可以使用FileStream

3) 使用ReadAllBytes

byte[] bytes = File.ReadAllBytes(path);

3

1:对于小文件,使用File.ReadAllBytes。

2:对于大文件,使用流(FileStream)或在流上使用BinaryReader——目的是通过更改代码以连续读取小块来消除需要分配大缓冲区的需求。

3:回到并查找预期大小;默认为最坏情况(#2)。

还请注意,我会尝试通过数据格式选择或压缩来尽量减小文件大小。


0

这个示例对于两种情况都很好 - 对于大文件,你需要使用缓冲读取。

 public static byte[] ReadFile(string filePath)
 {
  byte[] buffer;
  FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
  try
    {
     int length = (int)fileStream.Length;  // get file length
     buffer = new byte[1024];            // create buffer
     int count;                            // actual number of bytes read
     int sum = 0;                          // total number of bytes read

     // read until Read method returns 0 (end of the stream has been reached)
     while ((count = fileStream.Read(buffer, sum, length - sum)) > 0)
      sum += count;  // sum is a buffer offset for next reading
     }
     finally
     {
      fileStream.Close();
     }
      return buffer;
   }

这没有比File.ReadAllBytes更好的选择;为什么要重新发明轮子呢? - Marc Gravell
(这里的主要问题是需要为大文件分配一个巨大的缓冲区) - Marc Gravell
@Max Malygin:因为在你的代码中,你创建了一个与文件大小相同的缓冲区 - 在示例2中,你最终会得到一个长度为536,870,912字节而不是1,024字节的缓冲区 - 你基本上只是说“将所有内容读入我刚刚创建的巨大缓冲区中”,而不是说“好的,这个二进制文件的格式如下:前两个字节告诉我我有什么样的文件;接下来的50个字节是头部,包含以下细节:2个字节:元素数量;10个字节:元素长度;等等”,在那里你可以将你的读取分块,只读取你感兴趣的那些字节。 - Zhaph - Ben Duguid
是的,没错,抱歉需要更小一些...是我的错误。已经更正了。 - dexter
1
@Max - 这个还是不行,你最终会遇到一个异常:"偏移量和长度超出了数组的界限..."。你要求Read方法尝试将整个文件放入1024字节的数组(长度-总和)。如果你改为只读取1024字节,第二次仍然会有问题,因为你要求Read在数组结束后开始填充字节数组(从位置1024开始)。你的读取调用可能应该像这样:Read(buffer, 0, 1024),然后明确指出你需要处理缓冲区的内容。http://bit.ly/hxVLbH - Zhaph - Ben Duguid
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接