2012-02-11 4 views
1

В .NET мне нужен способ сравнения двух файлов. Я думал о классе, который представляет собой разницу:Получите разницу в двух файлах

public enum DiffEntryState 
{ 
    New, 
    Removed, 
    Changed 
}  
public class DiffEntry 
{ 
    public byte[] Bytes; 
    public long FileOffset; 
    public DiffEntryState State = BackupByteEntryState.Changed; 
} 

Имена должны быть довольно понятными. Я думал о добавлении состояния к каждой записи, чтобы я мог различать случаи, когда первый файл был больше второго или наоборот.

Мне интересно, если есть общий и быстрый способ получить байтовые байтовые различия двух файлов. Я бы просто создал поток для каждого файла и сравнивал куски этих потоков, пока не закончится. Есть ли лучший способ, или у Framework есть встроенное решение? Имейте в виду, что мне нужны сами различия, а не только отзывы, что есть различия.

// Edit:

После сна ночью над проблемой, я предполагаю, что я везу неправильный подход здесь. Весь инструмент - это резервное решение, которое сможет сохранять только измененные байты и тем самым уменьшать общее необходимое пространство для резервного копирования. Вместо сохранения сжатого файла размером 14 МБ каждый раз будет сохранено только 200 тыс. Или менее.

Но, подумав о проблеме, я понял, что этого будет недостаточно, чтобы сохранить только разницу побайтно. Возьмите текст, например:

«Это строка». «Это была строка».

На самом деле, единственное изменение здесь - это «есть» для «было». Но мой подход предполагает, что измененный контент теперь «был строкой». Если это происходит в начале огромного файла, ну, этот подход бесполезен. Очевидно, мне нужен способ индексирования файла и обнаружения всех перемещенных, скопированных или измененных блоков по сравнению с исходным файлом. Phew ...

+0

Какие файлы вам нужно сравнить? Текст? Изображений? ... –

+0

Файлы могут быть любого типа, поэтому я взял байтовый подход ... –

+0

В этом случае вы можете определить, что означает 'New',' Removed' и 'Changed', например, в файлах изображений? Или в файле '.doc'? Эти понятия вряд ли имеют смысл в общем случае. –

ответ

2

Нет встроенных функций.

Таким образом, вам нужно сравнить файлы байтов по байтам или использовать библиотеку, которая сделает это за вас.

2

Для стандартного двоичного разложения см. A Linear Time, Constant Space Differencing Algorithm Рэндала К. Бернса и Даррелла Д. Э. Лонг. Кроме того, магистерская диссертация Рэндала Бернса, Differential Compression: A Generalized Solution For Binary Files, более подробно представлена ​​и содержит псевдокод для алгоритма.

Вы также можете получить некоторые полезные идеи от About Remote Differential Compression и от Optimizing File Replication over Limited-Bandwidth Networks using Remote Differential Compression

Для текстового файла разностей, я рекомендую начать с An O(ND) Difference Algorithm and Its Variations Юджином В. Майерс. Этот алгоритм можно использовать для разграничения любых двух последовательностей. Чтобы сравнить два текстовых файла, генерируйте последовательности хэш-кодов (например, вызывая string.GetHashCode()) для каждой строки в каждом файле. Затем запустите эти последовательности (например, IList) с помощью алгоритма Майерса, чтобы найти кратчайший скрипт редактирования (т. Е. Вставляет и удаляет), который преобразует первую последовательность во вторую.

Надеюсь, это поможет. Я являюсь автором Diff.Net и использует алгоритм Бернса для двоичного разложения и алгоритм Майера для разграничения текста. Исходный код для Diff.Библиотеки Net (Menees.Diffs и Menees.Diffs.Controls) доступны в соответствии с лицензией Apache, версия 2.0, а приведенные выше ссылки должны помочь вам реализовать собственное решение без необходимости запускать с нуля.

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