2008-10-17 6 views

ответ

1

Или вы можете сравнить два файла байт за байтом ....

+0

Это быстрее для ТОЛЬКО 2 файлов, чем для вычисления хеш-кода. У тебя есть. – TcKs 2008-10-17 08:45:16

25

Вот простое решение, которое просто читает оба файла и сравнивает данные. Он должен быть не медленнее, чем хэш-метод, поскольку оба метода должны будут прочитать весь файл. EDIT Как отмечают другие, эта реализация на самом деле несколько медленнее, чем метод хеширования, благодаря своей простоте. Ниже приведен более быстрый метод.

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

Вы можете изменить его, чтобы читать больше, чем один байт в то время, но внутренний поток файл уже должен быть буферизации данных, поэтому даже этот простой код должен быть относительно быстро.

EDIT Спасибо за отзыв о скорости здесь. Я все же утверждаю, что метод compare-all-bytes может быть таким же быстрым, как MD5-метод, поскольку оба метода должны читать весь файл. Я бы подозревал (но не знаю точно), что после того, как файлы были прочитаны, метод compare-all-bytes требует меньше фактического вычисления. В любом случае я дублировал ваши наблюдения за производительностью для своей начальной реализации, но когда я добавил некоторую простую буферизацию, метод compare-all-bytes был таким же быстрым. Ниже приведена буферизация, не стесняйтесь комментировать дальше!

РЕДАКТИРОВАТЬ Джон Б делает еще один хороший момент: в случае, когда файлы на самом деле различны, этот метод может остановиться, как только он находит первые иные байты, тогда как метод хэша должен прочитать полноту обоих файлов в каждом случае.

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

Что мне особенно нравится в этом вопросе, так это то, что вы столкнетесь с бинарной разницей на раннем этапе при сравнении больших файлов одинаковой длины. – 2008-10-17 17:58:30

Смежные вопросы