2008-10-17 10 views

Respuesta

1

O puede comparar los dos archivos byte por byte ....

+0

Es más rápido para SOLO 2 archivos que la computación con código hash. Tienes una. – TcKs

25

Aquí hay una solución simple, que solo lee los archivos y compara los datos. No debería ser más lento que el método hash, ya que ambos métodos tendrán que leer todo el archivo. EDITAR Según lo observado por otros, esta implementación es en realidad algo más lenta que el método hash, debido a su simplicidad. Vea a continuación un método más rápido.

static bool FilesAreEqual(string f1, string f2) 
{ 
    // get file length and make sure lengths are identical 
    long length = new FileInfo(f1).Length; 
    if(length != new FileInfo(f2).Length) 
     return false; 

    // open both for reading 
    using(FileStream stream1 = File.OpenRead(f1)) 
    using(FileStream stream2 = File.OpenRead(f2)) 
    { 
     // compare content for equality 
     int b1, b2; 
     while(length-- > 0) 
     { 
      b1 = stream1.ReadByte(); 
      b2 = stream2.ReadByte(); 
      if(b1 != b2) 
       return false; 
     } 
    } 

    return true; 
} 

Se puede modificarlo para leer más de un byte a la vez, pero el flujo de archivos interno ya debe estar amortiguando los datos, por lo que incluso este simple código debe ser relativamente rápido.

EDIT Gracias por los comentarios sobre la velocidad aquí. Sigo manteniendo que el método compare-all-bytes puede ser tan rápido como el método MD5, ya que ambos métodos tienen que leer todo el archivo. Sospecho (pero no estoy seguro) que una vez que se han leído los archivos, el método de comparar todos los bytes requiere menos cálculos reales. En cualquier caso, dupliqué tus observaciones de rendimiento para mi implementación inicial, pero cuando agregué un simple almacenamiento en búfer, el método de comparar todos los bytes fue igual de rápido. A continuación se muestra la implementación de almacenamiento en búfer, no dude en comentar más!

EDITAR Jon B hace otro buen punto: en el caso de que los archivos de hecho son diferentes, este método puede parar tan pronto como se encuentra el primer byte diferente, mientras que el método de hash tiene que leer la totalidad de ambos archivos en cada caso.

static bool FilesAreEqualFaster(string f1, string f2) 
{ 
    // get file length and make sure lengths are identical 
    long length = new FileInfo(f1).Length; 
    if(length != new FileInfo(f2).Length) 
     return false; 

    byte[] buf1 = new byte[4096]; 
    byte[] buf2 = new byte[4096]; 

    // open both for reading 
    using(FileStream stream1 = File.OpenRead(f1)) 
    using(FileStream stream2 = File.OpenRead(f2)) 
    { 
     // compare content for equality 
     int b1, b2; 
     while(length > 0) 
     { 
      // figure out how much to read 
      int toRead = buf1.Length; 
      if(toRead > length) 
       toRead = (int)length; 
      length -= toRead; 

      // read a chunk from each and compare 
      b1 = stream1.Read(buf1, 0, toRead); 
      b2 = stream2.Read(buf2, 0, toRead); 
      for(int i = 0; i < toRead; ++i) 
       if(buf1[i] != buf2[i]) 
        return false; 
     } 
    } 

    return true; 
} 
+1

Lo que me gusta particularmente de esto es que detectará una diferencia binaria desde el principio al comparar archivos grandes de la misma longitud. –