C#中的文件比较

时间:2009-03-23 04:39:54

标签: c# video file audio comparison

是否存在用于比较两个音频内容的内置类/方法/ 视频文件? 或者是否存在用于转换音频/视频的内置类/方法 文件到比特流?

6 个答案:

答案 0 :(得分:3)

您可以在两个文件流上使用System.Security.Cryptography中的哈希函数并进行比较。这很容易做到,适用于小文件。如果你的文件很大,如果你正在处理音频/视频,它们可能就是这样,那么读入文件并生成哈希可能需要一些时间。

答案 1 :(得分:3)

其他答案都很好 - 要么是散列(如果要将文件与多个候选者进行比较),要么是按字节比较(如果比较两个单个文件)。

以下是一些额外的想法:

首先,检查文件大小 - 如果它们不同,则不要浪费时间比较字节。这些都很快检查。

其次,尝试使用二进制切割方法从文件的末尾或中间搜索。

例如,假设您有这样的文件:

ABCDEFGHIJKLMNOP

然后将其修改为:

ABCDEF11GHIJKLMN

要使文件大小保持不变,并插入内容,其他字节将被“淘汰”。因此,二进制斩波方法可以用较少的读取来选择它(例如,在两个文件中寻找和读取字节SIZE / 2-10到SIZE / 2 + 10,并进行比较)。

你可以尝试结合这些技巧。如果你通过一个足够好的数据样本来处理,你可能会发现你比较的所有不同文件(例如):

  • 发现80%是因为文件大小不同(每个文件10毫秒)
  • 由于二进制印章(每个文件50ms)发现10%
  • 由于线性字节比较(每个文件2000毫秒)而发现10%

对整个文件执行二进制切换并不是那么聪明,因为我预计如果线性读取而不是寻找随机点,硬盘会更快。但是如果你检查SIZE / 2,然后检查SIZE / 4 + SIZE / 4x3,然后是SIZE / 8,进行5次迭代,你可能会发现大部分差异而不必进行逐字节比较。 只是一些想法。

此外,不是从文件的前面读取,也许尝试向后读取文件的末尾。同样,您可能会在概率上寻找时间,但在“插入”方案中,假设在文件的中途进行了更改,您可能会从结束开始比从开始更快地发现这一点。

答案 2 :(得分:2)

您可以对这两个文件进行逐字节比较。 System.IO.File.ReadAllBytes(...)对此很有用。

答案 3 :(得分:2)

没有比较文件的直接方法。你必须处理音频/视频文件,这将是相对较大的,我不知道Bitwise比较将工作与否。

答案 4 :(得分:2)

示例: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;
}

答案 5 :(得分:1)

示例:在.NET中生成SHA1和MD5哈希(C#)

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;
}