Избегайте обновления даты и времени последнего обращения при чтении файла

#windows #ntfs #lastaccesstime

#Windows #ntfs #время последнего доступа

Вопрос:

Мы создаем приложение на базе Windows, которое рекурсивно просматривает структуру каталогов, ищет файлы, соответствующие определенным критериям, а затем выполняет с ними некоторую обработку. Чтобы решить, обрабатывать конкретный файл или нет, мы должны открыть этот файл и прочитать часть его содержимого.

В принципе, этот подход кажется отличным, но некоторые пользователи, тестирующие раннюю версию приложения, сообщили, что он изменяет время последнего обращения к большому количеству их файлов (неудивительно, поскольку фактически осуществляется доступ к файлам). Это проблема для этих клиентов, потому что у них есть политики архивирования, основанные на времени последнего обращения к файлам (например, они архивируют файлы, к которым не было доступа за последние 12 месяцев). Поскольку наше приложение планируется запускать чаще, чем «окно» архива, мы эффективно предотвращаем архивацию любого из этих файлов.

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

Итак, вот вопрос: есть ли вообще какой-либо способ в среде Windows, чтобы мы могли прочитать файл без обновления времени последнего обращения?

Заранее спасибо!

РЕДАКТИРОВАТЬ: Несмотря на тег «ntfs», на самом деле мы не можем полагаться на файловую систему, являющуюся NTFS. Многие наши клиенты запускают наше приложение по сети, поэтому на другом конце может быть что угодно.

Ответ №1:

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

Чтобы сохранить существующее время последнего доступа к файлу даже после обращения к файлу, вызовите SetFileTime сразу после открытия дескриптора файла с элементами структуры FILETIME этого параметра, инициализированными в 0xFFFFFFFF.

Комментарии:

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

2. Это не решило мою проблему на 100%, но я принимаю это, поскольку это, вероятно, будет лучшим ответом для большинства людей, задающих один и тот же вопрос.

3. Кто-нибудь заметил какие-либо несоответствия с тем, как установлен disablelastaccess, и трюком 0xffffffff в отношении удаленных UNC-файлов? Я вижу странное поведение, когда эта документированная процедура, похоже, работает не так, как ожидалось.

Ответ №2:

Начиная с Vista, NTFS по умолчанию не обновляет время последнего доступа. Чтобы включить это, см.http://technet.microsoft.com/en-us/library/cc959914.aspx

Запуск транзакции NTFS и откат очень плохи, и производительность будет ужасной.

Вы также можете сделать

Поведение FSUTIL установлено disablelastaccess 0

Комментарии:

1. Ваше первое предложение неверно, по крайней мере, если вы основываете его на ссылке. В нем говорится: «Определяет, обновляет ли NTFS временную метку последнего доступа в каждом каталоге при перечислении каталогов на томе NTFS».

Ответ №3:

Я не знаю, каковы минимальные требования вашего клиента, но пробовали ли вы транзакции NTFS? На рабочем столе первой ОС, поддерживающей это, была Vista, а на сервере — Windows Server 2008. Но, возможно, на это стоит взглянуть.

Запустите транзакцию NTFS, прочитайте ваш файл, откатите транзакцию. Просто! :-). На самом деле я не знаю, откатит ли это дату последнего доступа. Вам придется протестировать это самостоятельно.

Вот ссылка на статью в журнале MSDN о транзакциях NTFS, которая включает другие ссылки. http://msdn.microsoft.com/en-us/magazine/cc163388.aspx

Надеюсь, это поможет.

Комментарии:

1. Интересно… возможно, мы сможем это использовать. Я знаю, что пометил этот вопрос «ntfs», но мы не можем гарантировать, что файловой системой является NTFS (это может быть что угодно, включая NFS, NetWare или что-то столь же странное).

2. Ах, да, это строго функция NTFS, также нет FAT32. Удачи и держите нас в курсе. Мне также понравилась идея от Luke использовать SetFileTime, но если вы используете управляемый код (.NET), это означало бы использование вызова P / Invoke, поскольку вы не можете передать «-1» в качестве даты и времени в управляемом коде. P/Invoke SetFileTime . Предполагая, что это даже выполнимо с вашей сторонней библиотекой.

3. Хорошо, вот мысль (незнание вашего продукта или полных требований). Как насчет сочетания технологий. Если у клиента NTFS возникла проблема с резервным копированием неизмененного файла, когда вы сбрасываете дату последнего доступа обратно после ваших чтений, попробуйте TxF (транзакционная NTFS), в противном случае не делайте этого. Теперь вы можете определить, что такое базовая файловая система, а можете и не определить, так что ее, возможно, придется настраивать вручную. Просто так.

4. Да, я начинаю думать о смешанном решении с грубым «переписать время последнего обращения» в качестве последнего средства. Мы не используем управляемый код для этой части приложения (родной C ), так что это не проблема.