[C#] Побайтное сравнение файлов!

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Jakeroid, 17 May 2011.

  1. Jakeroid

    Jakeroid Member

    Joined:
    9 May 2009
    Messages:
    198
    Likes Received:
    12
    Reputations:
    1
    Есть функция:
    Code:
            private bool CompareFilesCheck(string file1_path, string file2_path)
            {
                StreamReader file1_sr = new StreamReader(file1_path);
                StreamReader file2_sr = new StreamReader(file2_path);
                while (!file1_sr.EndOfStream)
                {
                    if (file2_sr.EndOfStream)
                        return false;
                    if (file1_sr.Read() != file2_sr.Read())
                        return false;
                }            
                file1_sr.Dispose();
                file2_sr.Dispose();
                return true;
            }
    Сравнивать, она то сравнивает, но 1.5 гб файлы, уж очень долго сравнивает.

    Какие есть алгоритмы, или способы ускорить?
     
  2. Spot

    Spot Elder - Старейшина

    Joined:
    1 Mar 2007
    Messages:
    461
    Likes Received:
    38
    Reputations:
    1
    Довольно инетерсная тема, единственная идея это воспользоваться резкой файла на хэши, как это реализовано в p2p edonkey http://habrahabr.ru/blogs/p2p/118171/
    То бишь порезать файл на ломти md-4 хэши, после чего скрепить либо скрепить их воодине и проверить с аналагично нарезанным другим файлом, либо проверять каждую пару ломтев поотдельности, зависит от того- какой результат должен быть в конце - однозначный ответ о идентичности или отсутствия таковой двух файлов, либо конкретное выявление ломтя, в котором есть различия и уж тогда - побитная проверка этих кусков.

    ЗЫ, тоже интересна эта тема, если кто найдёт, что более конкретное или может поведать о других декарабхач- буду рад.
     
  3. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    самый лучший вариант - чтение файлов по кластерам и сравнения памяти
    т.к. размер кластера кратен 4 то и скорость сравнения будет намного больше. А если еще и заюзать нормальные функции сравнения (MMX/SSE) то еще быстрее.
    Скорость чтения файлов по кластерам почти такая же как и по одному байту.
    За исключением того, что тут за раз ты считываешь 1 байт, а там 1 кластер (что в принципе 4096 килобайт часто )
    А вообще самый лучший вариант вообще читать данные кратные размеру кластера, но не более чем кеш у винта. идеал 32768 и 65536 байта.
     
  4. Jakeroid

    Jakeroid Member

    Joined:
    9 May 2009
    Messages:
    198
    Likes Received:
    12
    Reputations:
    1
    Если я буду использовать функции C#, например:
    Stream A = File.OpenRead();
    А потом считывать по 4000000 байт например?
    Или лучше все это дело на Си написать, в длл запихнуть а потом использовать?
     
  5. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    2 fd00ch читать по кластерно - это самое главное. Если не веришь сделатьй тест: читать по 4096*4 байт или по 4096*4 + 1 байт и там сразу заметишь разницу в производительности. Потому что это всё фишки файловой системы.

    >> Чем меньше блок тем быстрее сравнивается.
    Сравнить 1000 блоков по 100 байт будет работать на порядок медленнее чем 1 блок размером 100000 байт.

    Но всё равно это занимает минимум времени так как самое большое ограничение это винт.

    Есть другой хороший метод - файл маппинг. через него блоками можно отображать файл в память. тем самым ты экономишь время которое тратится на копирование данных их системного буфера в твой буфер
     
    #5 slesh, 18 May 2011
    Last edited: 18 May 2011
  6. ShkiperLol

    ShkiperLol Banned

    Joined:
    17 Apr 2010
    Messages:
    182
    Likes Received:
    1
    Reputations:
    0
    Equals, Compare
     
  7. AlexTheC0d3r

    AlexTheC0d3r Elder - Старейшина

    Joined:
    25 Jul 2008
    Messages:
    388
    Likes Received:
    179
    Reputations:
    18
    смысла нет.
    В чем профит от того, что ты поделишь на блоки 1-10мб?
    сравнивать все-равно надо будет блоки размером с размер кластера
     
  8. X-rus

    X-rus Member

    Joined:
    22 Dec 2010
    Messages:
    88
    Likes Received:
    22
    Reputations:
    4
    Если не нужна сверхточность, то можно сравнивать только определённый процент файла.
     
  9. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Выгодней сравнивать блоки побольше, хотя бы потому что вызова функции сравнения будет меньше, но тут опять же надо искать компромисс "память/производительность".

    Читать надо действительно, в идеале, размером в кластер.