在C#中搜索大型二进制文件中十六进制值的有效方法是什么?

3

我正在实现一个程序,类似于HxD编辑器中的相同功能,它可以在大于1 GB的大二进制文件中搜索特定的十六进制值(例如32位)。由于内存有限,使用BinaryReader类逐块读取速度相当慢。HxD在大约12秒钟内返回搜索结果(接近文件末尾),这是可以接受的。


你说的“搜索十六进制值”是指“搜索字节序列”还是“搜索以十六进制形式表示的数字文本'0xff123456'”?另外,请展示代码,因为很难理解你为什么声称BinaryReader很慢... - Alexei Levenkov
1个回答

5

BinaryReader应该能够在12秒内读取1GB的数据,前提是您的磁盘子系统可以处理它(很明显可以,因为HxD正在这样做)。关键是使用更大的输入缓冲区打开文件。也就是说,不要像这样:

var f = File.OpenRead(filename)

调用

var f = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.None, 65536);

这将导致.NET以64 KB块而不是默认的4 KB块读取文件。

尽管为什么要使用BinaryReader仍然是一个谜。为什么不直接读取流呢?例如:

var buff = new byte[1024*1024];
int bytesRead = f.Read(buff, 0, buff.Length);

使用64 KB的文件缓冲区,.NET只需要进行16次调用来完成您的请求。如果使用默认的4K缓冲区,则需要进行256次调用。差异是显著的。

使用大于64 KB的缓冲区大小并不能带来太多的性能提升。而且在我的测试中,大于256 KB的缓冲区实际上会导致系统读取速度变慢。至少在我测试过的系统上,64 KB似乎是“最佳选择”。

如果出于某种原因决定使用BinaryReader,则应该期望使用更大的缓冲区也能带来类似的性能提升。


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