Сравнение двух файлов в С#

Я хочу сравнить два файла на С# и посмотреть, отличаются ли они. У них одинаковые имена файлов, и они имеют одинаковый размер, если они разные. Мне просто интересно, есть ли быстрый способ сделать это без необходимости вручную входить и читать файл.

Спасибо

Ответы

Ответ 1

В зависимости от того, насколько вы хотите его принять, вы можете взглянуть на Diff.NET

Здесь простая функция сравнения файлов:

// This method accepts two strings the represent two files to 
// compare. A return value of 0 indicates that the contents of the files
// are the same. A return value of any other value indicates that the 
// files are not the same.
private bool FileCompare(string file1, string file2)
{
     int file1byte;
     int file2byte;
     FileStream fs1;
     FileStream fs2;

     // Determine if the same file was referenced two times.
     if (file1 == file2)
     {
          // Return true to indicate that the files are the same.
          return true;
     }

     // Open the two files.
     fs1 = new FileStream(file1, FileMode.Open, FileAccess.Read);
     fs2 = new FileStream(file2, FileMode.Open, FileAccess.Read);

     // Check the file sizes. If they are not the same, the files 
        // are not the same.
     if (fs1.Length != fs2.Length)
     {
          // Close the file
          fs1.Close();
          fs2.Close();

          // Return false to indicate files are different
          return false;
     }

     // Read and compare a byte from each file until either a
     // non-matching set of bytes is found or until the end of
     // file1 is reached.
     do 
     {
          // Read one byte from each file.
          file1byte = fs1.ReadByte();
          file2byte = fs2.ReadByte();
     }
     while ((file1byte == file2byte) && (file1byte != -1));

     // Close the files.
     fs1.Close();
     fs2.Close();

     // Return the success of the comparison. "file1byte" is 
     // equal to "file2byte" at this point only if the files are 
     // the same.
     return ((file1byte - file2byte) == 0);
}

Ответ 2

Мне просто интересно, есть ли быстрый способ сделать это без необходимости вручную входить и читать файл.

Не совсем.

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

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

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

Ответ 3

Ну, я не уверен, можете ли вы в файле записать метки времени. Если нет, ваша уникальная альтернатива - это сравнение содержимого файлов.

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

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

    public static string CalcHashCode(string filename)
    {
        FileStream stream = new FileStream(
            filename,
            System.IO.FileMode.Open,
            System.IO.FileAccess.Read,
            System.IO.FileShare.ReadWrite);

        try
        {
            return CalcHashCode(stream);
        }
        finally
        {
            stream.Close();
        }
    }

    public static string CalcHashCode(FileStream file)
    {
        MD5CryptoServiceProvider md5Provider = new MD5CryptoServiceProvider();
        Byte[] hash = md5Provider.ComputeHash(file);
        return Convert.ToBase64String(hash);
    }

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

Ответ 4

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

Ответ 5

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

byte[] fileHash1, fileHash2;

using (SHA256Managed sha = new SHA256Managed())
{
    fileHash1 = sha.ComputeHash(streamforfile1);
    fileHash2 = sha.ComputeHash(streamforfile2);
}

for (int i = 0; (i < fileHash1.Length) && (i < fileHash2.Length); i++)
    {
        if (fileHash[i] != fileHash2[i]) 
        { 
             //files are not the same
             break; 
        }
    }

Ответ 6

Если они не соответствуют файлам, используйте инструмент diff, например KDiff или WinMerge. Он будет подчеркивать, что они разные.

http://kdiff3.sourceforge.net/

http://winmerge.org/

Ответ 7

передать каждый поток файлов через хешер MD5 и сравнить хэши.