我有一个包含PNG编码图像字节的MemoryStream,想检查磁盘上的某个目录中是否有该图像数据的精确副本。第一个明显的步骤是只查找与精确长度匹配的文件,但在此之后,我想知道什么是最有效的方法来比较内存和文件。我对流不是很有经验。
我对这件事有几个想法:
首先,如果我能得到文件的哈希码,那么(大概)比较哈希码比图像的每个字节更有效。同样,我可以只比较图像的一些字节,给出一个“足够接近”的答案。
当然,我可以比较整个流,但我不知道有多快。
比较MemoryStream和文件的最佳方法是什么?在for循环中逐字节比较?
6条答案
按热度按时间tez616oj1#
另一个解决方案是:
字符串
n53p2ov02#
首先,获取两个流的hashcode没有帮助-要计算hashcode,您需要读取整个内容 * 并在阅读时执行一些简单的计算。如果您逐字节或使用缓冲区比较文件,那么您可以提前停止(在您找到前两个字节/块之后)不匹配。
但是,如果您需要将
MemoryStream
与多个文件进行比较,则这种方法是有意义的,因为这样您只需要循环MemoryStream
一次(以计算hashcode),然后循环所有文件。在任何情况下,你都必须写代码来读取整个文件。正如你提到的,这可以通过逐字节或使用缓冲区来完成。阅读数据到缓冲区是一个好主意,因为当从HDD中阅读时(例如,阅读1 kB缓冲区),它可能是更有效的操作。此外,如果你需要并行处理多个文件,你可以使用异步
BeginRead
方法。摘要:
如果您需要并行处理多个文件,请使用
BeginRead
异步实现上述步骤。b1zrtrql3#
首先,获取两个流的散列码没有帮助--要计算散列码,您需要读取整个内容,并在阅读时执行一些简单的计算。
我不确定是我误解了它,还是这根本就不是真的。
字符集
我在benchmark.net上测试过这个代码,它在900 Mb的文件上分配了384个字节。
但这是真的
注意哈希冲突的可能性(不太可能)是很重要的。字节比较是避免这个问题的必要手段。
因此,如果哈希值不匹配,您必须执行额外的检查,以确保文件是100%不同的。在这种情况下,以下是一个很好的方法。
正如您提到的,这可以通过逐字节或使用缓冲区来完成。将数据读入缓冲区是一个好主意,因为从HDD读取数据(例如读取1 kB缓冲区)时,这可能是一个更有效的操作。
最近,我不得不执行这样的检查,所以我将发布此练习的结果作为2个实用程序方法
型
ercv8c1e4#
我们在NeoSmart Technologies开源了a library来处理这个问题,因为我们不得不比较不透明的
Stream
对象的字节相等性。它在NuGet上以StreamCompare
的形式提供,你可以阅读它相对于现有方法in the official release announcement的优势。用法非常简单:
字符集
它尽可能地消除了许多陷阱和性能陷阱,并包含了许多优化来加速比较(并最大限度地减少内存使用)。包中还包含一个文件比较 Package 器
FileCompare
,可用于按路径比较两个文件。StreamCompare
在MIT许可证下发布,可在.NET Standard 1.3及更高版本上运行。适用于.NET Standard 1.3、.NET Standard 2.0、.NET Core 2.2和.NET Core 3.0的NuGet软件包可用。完整文档在README
文件中。l5tcr1uw5#
rdfind有一个有趣的算法。除了比较大小之外,它还首先查看第一个和最后一个字节(由于标准化的文件头,第一个字节通常是相同的)。参见rdfind
smtd7mpg6#
使用
Stream
我们不会得到结果,每个文件都有一个唯一的标识,例如最后修改日期等。因此每个文件都是不同的。这些信息包含在流中