В практике разработчика 1С часто возникает задача проверки идентичности двух файлов. Это может быть необходимо для предотвращения дублирования изображений в базе данных, контроля версий документов или проверки целостности переданных данных. На первый взгляд задача кажется простой, но она имеет множество технических нюансов, начиная от производительности и заканчивая особенностями метаданных конкретных форматов файлов. В этой статье мы подробно разберем все доступные инструменты и методики, которые позволяют эффективно решить этот вопрос.
Самый распространенный и надежный с точки зрения программирования способ — это вычисление контрольной суммы (хеша) файла. Если хеши двух файлов совпадают, то с огромной долей вероятности (близкой к 100%) файлы бинарно идентичны. В платформе 1С для этого предназначен объект ХешированиеДанных.
Давайте проанализируем, как реализовать этот алгоритм на практике. Мы создадим объект, укажем алгоритм хеширования и добавим файл для обработки. Рассмотрим пример кода:
Функция ФайлыИдентичныЧерезХеш(ПутьКФайлу1, ПутьКФайлу2) Экспорт
ХешОбъект1 = Новый ХешированиеДанных(АлгоритмХеширования.MD5);
ХешОбъект1.ДобавитьФайл(ПутьКФайлу1);
Хеш1 = ХешОбъект1.ХешСумма;
ХешОбъект2 = Новый ХешированиеДанных(АлгоритмХеширования.MD5);
ХешОбъект2.ДобавитьФайл(ПутьКФайлу2);
Хеш2 = ХешОбъект2.ХешСумма;
Возврат Хеш1 = Хеш2;
КонецФункции
Разберем особенности выбора алгоритма:
АлгоритмХеширования.SHA256, если вам нужна максимальная надежность.Вычисление хеша требует чтения всего файла с диска, что может быть накладным для больших данных. Мы можем значительно ускорить процесс, если сначала сравним размеры файлов. Если размеры в байтах различаются, файлы гарантированно разные, и нам не нужно тратить ресурсы процессора на вычисление контрольных сумм.
Рассмотрим улучшенный алгоритм совместной проверки:
Функция ФайлыИдентичныОптимизировано(ПутьКФайлу1, ПутьКФайлу2)
Файл1 = Новый Файл(ПутьКФайлу1);
Файл2 = Новый Файл(ПутьКФайлу2);
// Если размеры разные, файлы точно не одинаковы
Если Файл1.Размер() <> Файл2.Размер() Тогда
Возврат Ложь;
КонецЕсли;
// Если размеры совпали, проверяем содержимое через хеш
Возврат ФайлыИдентичныЧерезХеш(ПутьКФайлу1, ПутьКФайлу2);
КонецФункции
Такой подход позволяет мгновенно отсеивать заведомо разные объекты, особенно если вы обрабатываете большие массивы картинок или архивов.
Платформа 1С предоставляет специализированный объект СравнениеФайлов. Чаще всего его используют для текстовых файлов или модулей, чтобы визуально показать различия пользователю. Однако программно его также можно использовать для проверки факта идентичности.
Посмотрим, как работает метод Сравнить(). Этот метод не возвращает булево значение напрямую, а создает файл с результатом сравнения или выводит диалоговое окно. Для автоматизированных систем этот метод менее удобен, чем хеширование, но он незаменим, если нужно сформировать отчет о расхождениях в текстовых данных.
В ситуациях, когда использование хешей по каким-то причинам невозможно или требуется абсолютная 100% уверенность без риска коллизий, мы можем реализовать побайтовое сравнение. Чтобы не перегружать оперативную память (например, при сравнении файлов объемом в несколько гигабайт), мы будем читать данные порциями (буферами).
Выясним, как это реализовать с помощью ЧтениеДанных:
Функция ПобайтовоеСравнение(Путь1, Путь2)
Файл1 = Новый ЧтениеДанных(Путь1);
Файл2 = Новый ЧтениеДанных(Путь2);
РазмерБуфера = 65536; // 64 КБ
Пока Истина Цикл
Буфер1 = Файл1.Прочитать(РазмерБуфера);
Буфер2 = Файл2.Прочитать(РазмерБуфера);
Если Не Буфер1.ПолучитьДвоичныеДанные().Сравнить(Буфер2.ПолучитьДвоичныеДанные()) = 0 Тогда
Возврат Ложь; // Найдено различие
КонецЕсли;
Если Буфер1.Размер() < РазмерБуфера Тогда
Прервать; // Файл закончился
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
Этот метод гарантирует точность, так как проверяется каждый бит информации. Однако на практике ХешированиеДанных работает быстрее за счет внутренних оптимизаций платформы.
Проанализируем ситуацию с графическими файлами, которая упоминалась в обсуждении. Это критически важный момент: два изображения могут выглядеть абсолютно одинаково для глаза, но быть разными для программы.
Причины бинарного различия визуально одинаковых JPG-файлов:
Если ваша задача — найти визуальные дубликаты, бинарное сравнение может не подойти. В этом случае требуется использование внешних библиотек для анализа "перцептивного хеша" (pHash), который сравнивает именно структуру изображения, а не байты. Но если цель — найти в точности тот же самый файл, то ХешированиеДанных — лучший выбор. Для практического выявления графических дубликатов среди файлов и ресурсов системы можно использовать обработку для поиска похожих изображений.
Для серверных решений под управлением Windows можно рассмотреть вариант вызова системной утилиты fc (file compare) в режиме бинарного сравнения /b. Это может быть полезно для очень больших файлов, так как операционная система оптимизирует такие операции на уровне файловой системы.
Пример вызова через 1С:
Команда = "fc /b """ + Путь1 + """ """ + Путь2 + """";
КодВозврата = 0;
ЗапуститьПриложение(Команда, , Истина, КодВозврата);
Если КодВозврата = 0 Тогда
// Файлы идентичны
КонецЕсли;
Важно: этот метод привязывает ваше решение к операционной системе и требует правильной обработки прав доступа к командной строке.
Подводя итог, выделим оптимальный алгоритм действий для разработчика 1С:
Файл.Мы рассмотрели основные инструменты платформы 1С для сопоставления файлов. Комбинируя эти методы, вы сможете создать быстрое и надежное решение для любой бизнес-задачи.