[英]File comparison in C#
是否有任何内置类/方法来比较两个音频/视频文件的内容? 或者是否有任何内置类/方法将音频/视频文件转换为位 stream?
您可以在两个文件流上使用 System.Security.Cryptography 中的 hash 函数并进行比较。 这很容易做到,并且适用于小文件。 如果您的文件很大,如果您正在处理音频/视频,则可能是这样,那么读取文件并生成 hash 可能需要一些时间。
其他答案很好 - 散列(如果您将文件与多个候选者进行比较)或逐字节比较(如果比较两个单个文件)。
以下是一些额外的想法:
首先,检查文件大小——如果它们不同,那么不要浪费时间比较字节。 这些可以快速检查。
其次,尝试使用二分法从文件的末尾或中间进行搜索。
例如,假设你有一个这样的文件:
ABCDEFGHIJKLMNOP
然后修改成这样:
ABCDEF11GHIJKLMN
为了使文件大小保持不变,并且要插入内容,其他字节将被“剔除”。 因此,二进制切分方法可能会以更少的读取来解决这个问题(例如,从两个文件中查找和读取字节 SIZE/2-10 到 SIZE/2+10,并进行比较)。
你可以尝试结合这些技术。 如果您对所处理的数据的足够好的样本进行此操作,您可能会发现您比较的所有不同文件(示例):
对整个文件进行二进制切碎不会那么聪明,因为我希望如果线性读取而不是寻找随机点,硬盘会更快。 但是,如果您检查 SIZE/2,然后是 SIZE/4+SIZE/4x3,然后是 SIZE/8,例如 5 次迭代,您可能会发现大部分差异,而无需进行逐字节比较。 只是一些想法。
另外,不是从文件的前面读取,而是尝试从文件的末尾向后读取。 同样,您可能会用寻找时间来换取概率,但在“插入”场景中,假设在文件中途进行了更改,您可能会发现从末尾开始比从头开始更快。
示例:2 个文件的二进制比较
/// <summary>
/// Methode, die einen Binärvergleich von 2 Dateien macht und
/// das Vergleichsergebnis zurückliefert.
/// </summary>
/// <param name="p_FileA">Voll qualifizierte Pfadangabe zur ersten Datei.</param>
/// <param name="p_FileB">Voll qualifizierte Pfadangabe zur zweiten Datei.</param>
/// <returns>True, wenn die Dateien binär gleich sind, andernfalls False.</returns>
private static bool FileDiffer(string p_FileA, string p_FileB)
{
bool retVal = true;
FileInfo infoA = null;
FileInfo infoB = null;
byte[] bufferA = new byte[128];
byte[] bufferB = new byte[128];
int bufferRead = 0;
// Die Dateien überprüfen
if (!File.Exists(p_FileA))
{
throw new ArgumentException(String.Format("Die Datei '{0}' konnte nicht gefunden werden", p_FileA), "p_FileA");
}
if (!File.Exists(p_FileB))
{
throw new ArgumentException(String.Format("Die Datei '{0}' konnte nicht gefunden werden", p_FileB), "p_FileB");
}
// Dateiinfo wegen der Dateigröße erzeugen
infoA = new FileInfo(p_FileA);
infoB = new FileInfo(p_FileB);
// Wenn die Dateigröße gleich ist, dann einen Vergleich anstossen
if (infoA.Length == infoB.Length)
{
// Binärvergleich
using (BinaryReader readerA = new BinaryReader(File.OpenRead(p_FileA)))
{
using (BinaryReader readerB = new BinaryReader(File.OpenRead(p_FileB)))
{
// Dateistream blockweise über Puffer einlesen
while ((bufferRead = readerA.Read(bufferA, 0, bufferA.Length)) > 0)
{
// Dateigrößen sind gleich, deshalb kann hier
// ungeprüft auch von der 2. Datei eingelesen werden
readerB.Read(bufferB, 0, bufferB.Length);
// Bytevergleich innerhalb des Puffers
for (int i = 0; i < Math.Min(bufferA.Length, bufferRead); i++)
{
if (bufferA[i] != bufferB[i])
{
retVal = false;
break;
}
}
// Wenn Vergleich bereits fehlgeschlagen, dann hier schon abbruch
if (!retVal)
{
break;
}
}
}
}
}
else
{
// Die Dateigröße ist schon unterschiedlich
retVal = false;
}
return retVal;
}
您可以对这两个文件进行逐字节比较。 System.IO.File.ReadAllBytes(...) 将对此有用。
没有直接的方法来比较文件。 而且您必须处理音频/视频文件,这些文件会比较大,我不知道按位比较是否有效。
示例:在 .NET (C#) 中生成 SHA1 和 MD5 哈希
public static string GenerateHash(string filePathAndName)
{
string hashText = "";
string hexValue = "";
byte[] fileData = File.ReadAllBytes(filePathAndName);
byte[] hashData = SHA1.Create().ComputeHash(fileData); // SHA1 or MD5
foreach (byte b in hashData)
{
hexValue = b.ToString("X").ToLower(); // Lowercase for compatibility on case-sensitive systems
hashText += (hexValue.Length == 1 ? "0" : "") + hexValue;
}
return hashText;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.