2008-10-22 7 views
4

Мне нужно написать инструмент на C++ для определения измененных битов в файле по сравнению с другим файлом для репликации. Какой был бы лучший способ достижения этого?Лучший способ определения измененных данных в C++

У меня нет конкретной ОС или библиотеки в виду, я открыт для предложений. Моя основная цель - сократить объем сетевого трафика, связанного с тиражированием.

ответ

17

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

+0

Это на самом деле даже лучше, чем это - он использует скользящую контрольную сумму, которая может обнаруживать равные блоки, даже если они были перенесены в местоположения, не привязанные к блокам. – ephemient

+0

Пока я писал свой ответ, я понял, что вы забыли упомянуть о хорошей точке продажи rsync: он работает без одновременной синхронизации обеих версий файла на машине-отправителе. – Alexander

0

Я хотел бы начать, пытаясь некоторые реализации дифф (http://en.wikipedia.org/wiki/Diff)

+0

Diff обычно работает, сравнивая все данные. Не то, что вы хотите для снижения сетевого трафика ... – dmckee

+0

@dmckee, это зависит от точного сценария. В некоторых сценариях обе версии каждого файла доступны на машине отправителя. В этом случае вы можете генерировать diff/deltas, что приведет к значительно меньшему трафику, чем к rsync. – Alexander

3

Если вы не можете использовать Rsync как есть, проверьте librsync. Он старый, но код легко читать и улучшать.

0

предложение: использовать хеш-функцию & a divide & победить подход, чтобы сузить блок изменений (ов). Не совсем решение для предотвращения столкновений, но SHA-2 IMO может работать на вас.

2

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

Для создания эффективных различий ознакомьтесь с бинарным дельта-сжатием VCDIFF (RFC 3284). Одна хорошая реализация - xdelta (www.xdelta.org). Довольно легко реализовать декодер/декомпрессор, если вы хотите избежать использования xdelta на принимающей стороне из-за проблем с лицензией. Написание собственного генератора дифференциальных данных VCDIFF, создающего компактные различия, намного сложнее (например, поиск перемещенных блоков в качестве примера).

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

Смежные вопросы