2009-03-23 7 views
1

Existe-t-il une classe/méthode intégrée pour comparer le contenu de deux fichiers vidéo audio/ ? Ou existe-t-il une classe/méthode intégrée permettant de convertir un fichier audio/vidéo en flux binaire?Comparaison de fichiers en C#

+0

Voulez-vous l'équivalence ou peu comparaison sage? Qu'est-ce que je veux dire, vous pourriez avoir la même vidéo dans deux formats différents? Je suppose que vous voulez juste une comparaison un peu sage comme le premier, une comparaison sémantique, est beaucoup plus difficile. – BobbyShaftoe

+0

N'oubliez pas de comparer d'abord la longueur du fichier! –

+0

Vous devez définir ce que vous entendez par "contenu". Est-ce quantitatif? Est-ce qualitatif? Par exemple, que se passe-t-il si votre "contenu" signifie une gamme de disciples? Et si "contenu" signifiait genre de musique? Et si "contenu" signifiait tous les musiciens qui se sont identifiés comme hippie? – core

Répondre

2

Vous pouvez utiliser les fonctions de hachage dans System.Security.Cryptography sur deux flux de fichiers et les comparer. C'est facile à faire et fonctionne bien pour les petits fichiers. Si vos fichiers sont volumineux, ce qui est probablement le cas pour les fichiers audio/vidéo, la lecture dans le fichier et la génération du hachage peuvent prendre un peu de temps.

+0

Oui, c'est une bonne première si. En fait, vous pouvez utiliser MD5 et obtenir des performances assez décentes pour les petits fichiers. Cela dépend de l'exigence. Il est possible que deux fichiers différents aient le même hachage. Juste un aparté. – BobbyShaftoe

+0

Cependant, il vous donne une garantie rapide de NON. Probablement vous pourriez prendre le premier nombre X d'octets et hacher cela. Ensuite, allez à partir de là. – BobbyShaftoe

+0

Étant donné le nombre d'opérations dans un hachage, la comparaison des octets de fichiers serait-elle plus rapide? –

1

Vous pouvez effectuer une comparaison par octet des deux fichiers. System.IO.File.ReadAllBytes (...) serait utile pour cela.

+0

À droite, vous pouvez lire tous les octets et commencer à comparer. De toute évidence, commencez avec juste le nombre d'octets, puis comparez chaque octet. C'est une méthode simple à mettre en œuvre. – BobbyShaftoe

+0

Cela fonctionnerait, étiez-vous en train d'essayer d'identifier comment les fichiers d'identité sont. Cependant, à ce stade, nous ne savons pas ce que ce type essaie de faire. Le logiciel consiste à résoudre des problèmes. De vrais problèmes. Vous résolvez le problème de quelqu'un, vous avez un problème intellectuel et, espérons-le, un salaire. Sinon, dommage. – core

1

Les autres réponses sont bonnes - soit le hachage (si vous comparez le fichier à plusieurs candidats), soit une comparaison par octet (si vous comparez deux fichiers individuels).

Voici quelques réflexions supplémentaires:

d'abord, vérifiez la taille des fichiers - si elles sont différentes, alors ne perdez pas de temps à comparer octets. Ceux-ci sont rapides à vérifier. Deuxièmement, essayez de chercher à partir de la fin ou du milieu du fichier en utilisant une approche de hachage binaire.

Par exemple, supposons que vous avez un fichier comme celui-ci:

ABCDEFGHIJKLMNOP 

Ensuite, il est modifié à ceci:

ABCDEF11GHIJKLMN 

Pour la taille du fichier à rester le même, et content d'avoir été inséré , les autres octets seront "assommés". Donc, une approche de hachage binaire pourrait ramasser ceci avec moins de lectures (par exemple, dans rechercher et lire des octets TAILLE/2-10 à TAILLE/2 + 10 à partir des deux fichiers, et comparer).

Vous pourriez essayer de combiner les techniques. Si vous le faites sur un assez bon échantillon des données que vous traitez, vous trouverez peut-être celle de tous les différents fichiers que vous COMPARE (exemple):

  • 80% ont été parce que la taille du fichier était différent (10ms par fichier)
  • 10% étaient dus à hacher binaire (50ms par fichier)
  • 10% étaient dus à des comparaisons d'octets linéaires (2000ms par fichier)

Faire une côtelette binaire sur l'ensemble wouldn de fichiers ne soyez pas si intelligent, car je m'attends à ce que le disque dur soit plus rapide s'il lit linéairement plutôt que de chercher à m taches. Mais si vous cochez SIZE/2, puis SIZE/4 + SIZE/4x3, puis SIZE/8, par exemple 5 itérations, vous pourriez trouver la plupart des différences sans avoir à faire une comparaison par bytewise. Juste quelques idées. De plus, au lieu de lire depuis le début du fichier, essayez peut-être de lire à partir de la fin du fichier. Encore une fois, vous pouvez échanger votre temps de recherche sur la probabilité, mais dans le scénario «insérer», en supposant qu'une modification est faite à mi-chemin dans le fichier, vous trouverez probablement cela plus rapidement en commençant à la fin qu'au début.

1

Il n'existe aucun moyen direct de comparer des fichiers. Et vous devez traiter avec des fichiers audio/vidéo, ce qui sera relativement grand, je ne sais pas la comparaison Bitwise fonctionnera ou non.

0

Exemple: Génération SHA1 et hachage MD5 dans .NET (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; 
} 
1

Exemple: Comparaison binaire de 2 fichiers

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