Наиболее эффективный способ сравнения memorystream с файлом C#.NET

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

У меня была пара мыслей на этот счет:

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

и тогда, конечно, я мог бы просто сравнить весь поток, но я не знаю как быстро это будет.

каков наилучший способ сравнить MemoryStream с файлом? Побайтовое в цикле for?

3 ответов


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

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

в любом случае, вам придется написать код, чтобы прочитать весь файл. Как вы уже упоминали, это можно сделать либо байт за байтом, либо с помощью буферов. Чтение данных в буфер-хорошая идея, потому что это может быть более эффективная работа при чтении с жесткого диска (например, чтение буфера 1kB). Кроме того, вы можете использовать асинхронный BeginRead метод, если вам нужно обработать несколько файлов параллельно.

резюме:

  • Если вам нужно сравнить несколько файлов, используйте hashcode
  • для чтения / сравнения содержимого одного файла:
    • чтение 1 кб данных в буфер из обоих потоков
    • посмотрите, есть ли разница (если да, выйти)
    • продолжения цикла

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


другое решение:

private static bool CompareMemoryStreams(MemoryStream ms1, MemoryStream ms2)
{
    if (ms1.Length != ms2.Length)
        return false;
    ms1.Position = 0;
    ms2.Position = 0;

    var msArray1 = ms1.ToArray();
    var msArray2 = ms2.ToArray();

    return msArray1.SequenceEqual(msArray2);
}

С помощью Stream мы не получаем результат, каждый файл имеет уникальную идентичность, такую как дата последнего изменения и так далее. Таким образом, каждый файл отличается. Эта информация включена в поток