Как я могу определить на С#, являются ли два файла абсолютно одинаковыми (размер, содержимое и т.д.)?
Управление файлами на С#
Ответ 1
Вот простое решение, которое просто считывает оба файла и сравнивает данные. Он должен быть не медленнее, чем хэш-метод, поскольку оба метода должны будут прочитать весь файл. 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 был таким же быстрым. Ниже приведена буферизация, не стесняйтесь комментировать дальше!
EDIT Джон Б делает еще одну хорошую точку: в случае, когда файлы на самом деле разные, этот метод может остановиться, как только он найдет первый бит, тогда как хэш-метод должен прочитать все файлы в каждом случае.
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;
}
Ответ 2
Или вы можете сравнить два байта байта для байта....