Подтвердить что ты не робот

Как работать, если файл был изменен?

Я пишу резервное решение (вроде). Просто он копирует файл из местоположения C:\и вставляет его в место Z:\

Чтобы скорость была быстрой, перед копированием и вставкой она проверяет, существует ли исходный файл. Если это так, он выполняет несколько "вычислений" для разработки, если копия должна быть продолжена или обновлен файл резервной копии. Именно эти расчеты мне кажутся трудными.

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

Итак, мне нужно выяснить, отличается ли измененная дата. На данный момент я получаю информацию о файле с помощью класса FileInfo, но после просмотра всех полей нет ничего подходящего.

Как я могу проверить, что я копирую файлы, которые были изменены?

ИЗМЕНИТЬ  Я видел предложения по SO для использования контрольных сумм MD5, но я обеспокоен тем, что это может быть проблемой, поскольку некоторые из файлов, которые я сравниваю, будут до 10 ГБ

4b9b3361

Ответ 1

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

Переход на бит архива может работать в контролируемой среде, но что произойдет, если будет запущено другое программное обеспечение, которое также использует бит архива?

Бит архива Windows является злым и должен быть остановлен

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

Вот класс SHA1 вместе с образцом кода внизу:

http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha1.aspx

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

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

Большинство систем управления версиями используют какой-то комбинированный подход с хешами и измененными датами.

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

Ответ 2

Вы можете сравнивать файлы по своим хэшам:

private byte[] GetFileHash(string fileName)
{
    HashAlgorithm sha1 = HashAlgorithm.Create();
    using(FileStream stream = new FileStream(fileName,FileMode.Open,FileAccess.Read))
      return sha1.ComputeHash(stream);
}

Если содержимое было изменено, хеши будут разными.

Ответ 3

Вам может понравиться ознакомиться с классом FileSystemWatcher.

"Этот класс позволяет вам отслеживать каталог для изменений и событие, когда что-то изменяется."

Затем ваш код может обрабатывать событие и обрабатывать файл.

Источник кода - MSDN:

// Create a new FileSystemWatcher and set its properties.
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = args[1];

/* Watch for changes in LastAccess and LastWrite times, and
   the renaming of files or directories. */
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
   | NotifyFilters.FileName | NotifyFilters.DirectoryName;

// Only watch text files.
watcher.Filter = "*.txt";

// Add event handlers.
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);

Ответ 4

Вообще говоря, вы позволили бы ОС позаботиться о том, изменился ли файл или нет.

Если вы используете:

File.GetAttributes

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

Вы можете легко проверить флаг в DOS, используя:

dir /aa yourfilename

Или просто добавьте столбец атрибутов в проводнике Windows.

Ответ 5

Флаг архива файлов обычно используется программами резервного копирования, чтобы проверить, требуется ли резервное копирование файла. Когда Windows изменяет или создает файл, он устанавливает флаг архива (см. здесь). Проверьте, установлен ли флаг архива, необходимо ли резервное копирование файла:

if ((File.GetAttributes(fileName) & FileAttributes.Archive) == FileAttributes.Archive)
{
    // Archive file.
}

После резервного копирования файла очистите флаг архива:

File.SetAttributes(fileName, File.GetAttributes(fileName) & ~FileAttributes.Archive);

Это означает, что никакие другие программы (например, программное обеспечение для резервного копирования системы) не очищают флаг архива.