比较两个任意格式的文件c#
本文关键字:格式 文件 任意 两个 比较 | 更新日期: 2023-09-27 18:28:18
我正在开发一个应用程序,该应用程序接收文件的两个文件夹中的任何一个,并将它们相互比较,并输出任何差异。我有一个部分,它获取两个文件的内容,然后输出文件名中的任何差异。现在,我想将两个文件夹中相同的文件进行比较,看看它们是否不同。我的第一个猜测是检查它们,看看二进制文件是否使用了字节读取器,我一直在尝试,但无法正常工作。我在下面找到了一个解决方案,但无法使其发挥作用。有人有一个起点或一些示例代码让我开始吗。我想尝试使它对任何文件类型都通用。即文本、docx、exe、pdf、mp3、mp4、xlsx。。。
static void Main(string[] args)
{
// Read the file into <bits>
try
{
var fs = new FileStream(Console.ReadLine(), FileMode.Open);
var len = (int)fs.Length;
var bits = new byte[len];
fs.Read(bits, 0, len);
// Dump 16 bytes per line
for (int ix = 0; ix < len; ix += 16)
{
var cnt = Math.Min(16, len - ix);
var line = new byte[cnt];
Array.Copy(bits, ix, line, 0, cnt);
// Write address + hex + ascii
Console.Write("{0:X6} ", ix);
Console.Write(BitConverter.ToString(line));
Console.Write(" ");
// Convert non-ascii characters to .
for (int jx = 0; jx < cnt; ++jx)
if (line[jx] < 0x20 || line[jx] > 0x7f) line[jx] = (byte)'.';
Console.WriteLine(Encoding.ASCII.GetString(line));
Console.Read();
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
Console.ReadLine();
}
}
在我看来,另一种更简单的方法是使用MD5哈希:
string filePath = @"C:'Users'Gabriel'Desktop'Test.txt";
string filePath2 = @"C:'Users'Gabriel'Desktop'Test2.txt";
string hash;
string hash2;
using (var md5 = MD5.Create())
{
using (var stream = File.OpenRead(filePath))
{
hash = BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLower();
}
using (var stream = File.OpenRead(filePath2))
{
hash2 = BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLower();
}
}
if (hash == hash2)
{
// Both files are the same, so you can do your stuff here
}
请注意,MD5哈希使用文件的内容来定义它们是否相同,但它不考虑其名称。因此,如果您创建了两个具有不同名称的相同文本文件,则会认为它们是相同的。如果你也需要它来检查名称,你可以尝试将最后一个If语句更改为类似的内容:
if (hash == hash2)
{
FileInfo file = new FileInfo(filePath);
FileInfo file2 = new FileInfo(filePath2);
if (file.Name == file2.Name)
{
// Both files are the same, so you can do your stuff here
}
}
这个类可能对比较文件有用:
public class FileComparator
{
private const int _bufferCapacity = 0x400000; //4Mb
public static bool AreEquals(string first, string second)
{
return AreEquals(File.OpenRead(first), File.OpenRead(second));
}
public static bool AreEquals(FileStream first, FileStream second)
{
using (var firstStream = new BufferedStream(first))
using (var secondStream = new BufferedStream(second))
{
if (first.Length != second.Length)
return false;
var firstBuffer = new byte[_bufferCapacity];
var secondBuffer = new byte[_bufferCapacity];
int bytesReadFirst;
int bytesReadSecond;
do
{
bytesReadFirst = firstStream.Read(firstBuffer, 0, firstBuffer.Length);
bytesReadSecond = secondStream.Read(secondBuffer, 0, secondBuffer.Length);
if (bytesReadFirst != bytesReadSecond || !CompareByteArrays(firstBuffer, secondBuffer))
return false;
} while (bytesReadFirst > 0 && bytesReadSecond > 0);
return true;
}
}
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int memcmp(byte[] b1, byte[] b2, long count);
private static bool CompareByteArrays(byte[] first, byte[] second)
{
return first.Length == second.Length && memcmp(first, second, first.Length) == 0;
}
}
您可以通过将文件名作为参数或仅作为流传递来使用它:
var result = FileComparator.AreEquals(Console.ReadLine(), Console.ReadLine());
如果不想在代码中使用"DllImport",可以用SequanceEquals
的调用来填充它,但速度会慢得多。