.NET 查找两个文件的相似性和差异性的最快方法

本文关键字:相似性 差异性 方法 文件 查找 两个 NET | 更新日期: 2023-09-27 18:34:10

我正在尝试制作一个文件比较程序,我想实现的功能之一是计算所选两个文件的相似性和差异性。我希望这种比较在大文件上快速(如果可能的话)。我不确定应该使用什么方法,但最终我想要一个百分比。

参考此 gif 以获得视觉创意。

.NET 查找两个文件的相似性和差异性的最快方法

您可能希望像二进制差异实用程序所看到的相似性一样 - 而不是一个愚蠢的逐字节比较。但是,嘿,只是为了好玩...

unsafe static long DumbDifference(string file1Path, string file2Path)
{
    // completely untested! also, add some using()s here.
    // also, map views in chunks if you plan to use it on large files.
    MemoryMappedFile file1 = MemoryMappedFile.CreateFromFile(
             file1Path, System.IO.FileMode.Open,
             null, 0, MemoryMappedFileAccess.Read);
    MemoryMappedFile file2 = MemoryMappedFile.CreateFromFile(
             file2Path, System.IO.FileMode.Open,
             null, 0, MemoryMappedFileAccess.Read);
    MemoryMappedViewAccessor view1 = file1.CreateViewAccessor();
    MemoryMappedViewAccessor view2 = file2.CreateViewAccessor();
    long length1 = checked((long)view1.SafeMemoryMappedViewHandle.ByteLength);
    long length2 = checked((long)view2.SafeMemoryMappedViewHandle.ByteLength);
    long minLength = Math.Min(length1, length2);
    byte* ptr1 = null, ptr2 = null;
    view1.SafeMemoryMappedViewHandle.AcquirePointer(ref ptr1);
    view2.SafeMemoryMappedViewHandle.AcquirePointer(ref ptr2);
    ulong differences = (ulong)Math.Abs(length1 - length2);
    for (long i = 0; i < minLength; ++i)
    {
        // if you expect your files to be pretty similar,
        // you could optimize this by comparing long-sized chunks.
        differences += ptr1[i] != ptr2[i] ? 1u : 0u;
    }
    return checked((long)differences);
}

太糟糕了,.NET 没有内置的 SIMD 支持。

如果你可以使用linq,这应该没有问题。

var results = your1stEnumerable.Intersect(your2ndEnumerable);