2010-03-02 10 views
17

Powiedz, że mam plik A.doc.
, a następnie skopiuj go do b.doc i przenieś do innego katalogu.
dla mnie to wciąż ten sam plik.
ale jak mogę to ustalić?
podczas pobierania plików i czasami czytam o otrzymaniu czegoś mda5 lub sumy kontrolnej, ale nie wiem o co chodzi.jak sprawdzić, czy 2 pliki są równe przy użyciu .NET?

Czy istnieje sposób sprawdzenia, czy te pliki są binarne równe?

+0

Chcesz to zrobić programowo, w przeciwnym razie byłoby to lepiej nadaje się na SuperUser.com? – cjk

+0

Tak, tworzę mały program do usuwania duplikatów. – Michel

Odpowiedz

14

Jeśli chcesz być w 100% pewny, że dokładnie bajty w pliku są takie same, to otwarcie dwóch strumieni i porównywanie każdego bajtu plików jest jedynym sposobem.

Jeśli chcesz być całkiem pewny (99,9999%?), Obliczyć skrót MD5 każdego pliku i porównać skróty zamiast tego. Sprawdź System.Security.Cryptography.MD5CryptoServiceProvider.

W moich testach, jeśli pliki są zwykle równoważne, porównywanie skrótów MD5 jest około trzy razy szybsze niż porównywanie każdego bajtu pliku.
Jeśli pliki są zazwyczaj różne, porównywanie bajt po bajcie będzie znacznie szybsze, ponieważ nie musisz czytać całego pliku, możesz przestać, gdy tylko jeden bajt będzie się różnić.

Edytuj: Oryginalnie oparłem tę odpowiedź na szybkim teście, który odczytał każdy bajt po bajcie i porównał je bajt po bajcie. Fałszywie założyłem, że zbuforowana natura System.IO.FileStream uratowałaby mnie przed martwieniem się o rozmiary bloków dysku twardego i prędkości odczytu; to nie była prawda. Ponownie przetestowałem program, który czyta z każdego pliku w 4096 bajtowych porcjach, a następnie porównuje porcje - ta metoda jest nieco szybsza ogólnie niż MD5, nawet jeśli pliki są dokładnie takie same i oczywiście będą znacznie szybsze, jeśli się różnią.

Zostawiam tę odpowiedź jako łagodne ostrzeżenie dotyczące klasy FileStream, a ponieważ wciąż myślę, ma pewną wartość jako odpowiedź na pytanie "jak obliczyć MD5 pliku w .NET". Poza tym nie jest to najlepszy sposób na wypełnienie pierwotnego wniosku.

przykład obliczania skrótów MD5 dwóch plików (obecnie testowane!):

using (var reader1 = new System.IO.FileStream(filepath1, System.IO.FileMode.Open, System.IO.FileAccess.Read)) 
{ 
    using (var reader2 = new System.IO.FileStream(filepath2, System.IO.FileMode.Open, System.IO.FileAccess.Read)) 
    { 
     byte[] hash1; 
     byte[] hash2; 

     using (var md51 = new System.Security.Cryptography.MD5CryptoServiceProvider()) 
     { 
      md51.ComputeHash(reader1); 
      hash1 = md51.Hash; 
     } 

     using (var md52 = new System.Security.Cryptography.MD5CryptoServiceProvider()) 
     { 
      md52.ComputeHash(reader2); 
      hash2 = md52.Hash; 
     } 

     int j = 0; 
     for (j = 0; j < hash1.Length; j++) 
     { 
      if (hash1[j] != hash2[j]) 
      { 
       break; 
      } 
     } 

     if (j == hash1.Length) 
     { 
      Console.WriteLine("The files were equal."); 
     } 
     else 
     { 
      Console.WriteLine("The files were not equal."); 
     } 
    } 
} 
+4

Chociaż ten kod jest "krótszy", z pewnością jest znacznie wolniejszy i ogólnie gorszy od porównywania bajt po bajcie. Nie wspominając o MD5 jest martwym hash (kryptograficznie mówiąc). Naprawdę nie zrobiłbym tego, jeśli chcesz tylko sprawdzić, czy pliki są równe. –

+1

@silky: Podejrzewam, że zależy to od rozmiaru plików i tego, czy przypadek użycia ma większą szansę na ich równoważność, czy nie, ale obliczanie MD5 dwóch plików jest trzy razy szybsze niż porównywanie ich zawartości bajt po bajcie bajt. – Coxy

+7

@silky: MD5 będący martwym hash kryptograficznie ma niewiele wspólnego z jego użyciem jako mieszanie porównawcze dla dużego pliku. – Tanzelax

2

Rzeczywiście istnieje. Otwórz oba pliki, odczytaj je jako tablice bajtów i porównaj każdy bajt. Jeśli są równe, plik jest równy.

8

Najpierw porównaj rozmiar plików, jeśli rozmiar nie jest taki sam, to pliki są różne, jeśli rozmiar jest taki sam, po prostu porównaj zawartość plików.

Powiązane problemy