Можно ли сравнить двоичный файл в c #? - PullRequest
1 голос
/ 27 мая 2010

Я хочу заменить двоичный файл, если его содержимое отличается.

Так что мне нужно иметь возможность сравнивать двоичный файл (без необходимости десериализации).

Возможно ли это?

Я использовал двоичный форматер для сохранения файла.

Ответы [ 5 ]

12 голосов
/ 27 мая 2010

Да, это возможно.

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

Псевдокод будет:

  • Открыть файл1 и файл2 в виде потоков.
  • Начните с сравнения длины; если длина не равна, файлы не равны.
  • Чтение части каждого файла в буфер и сравнение буферов. Повторяйте, пока не столкнетесь с различиями или не достигните конца файла.

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

6 голосов
/ 27 мая 2010

Да, вы можете сгенерировать хэш MD5 или SHA1 для каждого набора файловых данных, а затем сравнить их.

Пример кода (проверка ошибок удалена для ясности):

public bool CompareFiles(string filePath1, string filePath2)
{

  FileInfo info1 = new FileInfo(filePath1);
  FileInfo info2 = new FileInfo(filePath2);


  byte[] data1 = new byte[info1.Length]
  byte[] data2 = new byte[info2.Length]; 

  FileStream fs1 = new FileStream(filePath1, FileMode.Open);
  FileStream fs2 = new FileStream(filePath2, FileMode.Open);

  fs1.Read(data1, 0, info1.Length);
  fs2.Read(data2, 0, info2.Length);

  fs1.Dispose();
  fs2.Dispose();

  SHA1 sha = new SHA1CryptoServiceProvider(); 

  byte[] hash1 = sha.ComputeHash(data1);
  byte[] hash2 = sha.ComputeHash(data2);

  // c# 2 or less: you need to compare the hash bytes yourself

  // c# 3.5/4
  bool result = hash1.SequenceEqual(hash2);

  return result;
}
0 голосов
/ 27 мая 2010

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

private static bool CompareFiles(string file1, string file2)
{
    var fsFile1 = new System.IO.FileStream(file1, System.IO.FileMode.Open, System.IO.FileAccess.Read);
    var fsFile2 = new System.IO.FileStream(file2, System.IO.FileMode.Open, System.IO.FileAccess.Read);
    var md5 = new System.Security.Cryptography.MD5Cng();
    var md5File1 = md5.ComputeHash(fsFile1);
    var md5File2 = md5.ComputeHash(fsFile2);
    for (int i = 0; i < md5File1.Length; ++i)
    {
        if (md5File1[i] != md5File2[i])
            return false;
    }
    return true;
}
0 голосов
/ 27 мая 2010

Вы можете прочитать двоичное содержимое файла и сравнить полученные байты. Для чтения файла вы можете либо использовать ReadAllBytes (если файл имеет разумный размер и удобно помещается в памяти), либо вы можете использовать FileStream и читать фрагменты данных из обоих файлов.

Структура подхода с использованием буферов может выглядеть следующим образом:

byte[] buffer1 = new byte[1024], buffer2 = new byte[1024];
using(var fs1 = new FileStream(firstFile, FileMode.Open, FileAccess.Read)
using(var fs2 = new FileStream(secondFile, FileMode.Open, FileAccess.Read)
{
  // Use: fs.Read(buffer1, 0, 1024) to repeatedly read 1kb of data
  // from both fs1 and fs2 and compare the content in buffer1 and buffer2
}

Некоторые люди рекомендуют использовать хэши, но это не очень хорошая идея - если файлы одинаковы, вам нужно прочитать все данные из файла, поэтому вычисление хэшей не эффективнее, чем простое чтение и сравнение всех данных , Однако, если файлы различаются в первых нескольких байтах, вам нужно будет прочитать только первые несколько байтов (при сравнении побайтно)!

Хеши были бы полезны, если вы хотите сравнить несколько файлов (например, каждый с каждым).

0 голосов
/ 27 мая 2010
byte[] myFile = File.ReadAllBytes(pathToFile);

Тогда пройдитесь по нему. Может быть медленным, если файл большой.

Возможно, вам следует искать файл алгоритма хеширования MD5

...