Рейтинг:1

Содержимое файла Windows не обновляется в проводнике/Powershell

флаг cf

На Windows Server средство ведения журналов постоянно записывает файлы .log на диск и ежедневно в полночь меняет файлы журналов. Каждый день создается новый файл журнала, но почти каждый день его содержимое / метаданные впоследствии не обновляются в проводнике Windows и Powershell.

Пример: файл был создан 17 мая 2022 года в 0:00. Он имеет размер примерно 24 КБ в проводнике Windows и имеет время последней записи около полуночи (точное время с точностью до секунды я не проверял). Если я использую Powershell

(Get-Item).Длина

У меня размер 24401.

Теперь, когда я щелкаю правой кнопкой мыши тот же файл в проводнике Windows и проверяю его свойства, он обновляет размер до 4593 КБ, а время последней записи — 17 мая 2022 года, 09:34. Точное время и размер на самом деле не имеют значения, но проблема заключается в следующем: почему проводник Windows и Windows Powershell полностью не синхронизированы с базовой файловой системой? Что вообще может вызвать такое несоответствие?

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

Копия-элемент "..исходный файл.." -Destination "..где-то.."

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

Кто-нибудь когда-нибудь был свидетелем такого поведения в Windows?

  • Файловая система: NTFS
  • ОС: Windows Server 2019, версия 1809, сборка 17763.2803
  • «Аппаратное обеспечение»: виртуальный сервер на сервере VMware ESXi.
Рейтинг:0
флаг cn

Да, это потому, что процесс все еще записывает в файл, а буферы не сбрасываются.

Как правило, когда вы хотите записать в файл, вы можете (примерно) сделать что-то вроде этого:

1. Создайте/откройте файл и извлеките «канал» (дескриптор) к файлу.
2. Напишите что-нибудь
3. Очистить буфер/закрыть файл «канал» (дескриптор) (= зафиксировать на диске)
(затем повторите 1, 2 и 3, когда захотите написать что-то снова)

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

Это означает, что если вы планируете часто записывать в файл, лучше просто Создать/Открыть файл, тогда Написать несколько раз, по мере необходимости, и когда вы закончите Румянец или закрыть дескриптор (в моем примере выше это означает 1, 2 [повторить шаг 2 по мере необходимости], затем, позже, 3)

И пока данные не сбрасываются на диск/коммитятся: на них нельзя полагаться!

Microsoft предоставляет более подробную информацию об этом:

Сброс данных ввода-вывода с системным буфером на диск

[...] Windows сохраняет данные операций чтения и записи файлов в буферах данных, поддерживаемых системой, для оптимизации производительности диска. Когда приложение записывает данные в файл, система обычно буферизует данные и регулярно записывает их на диск[...]

FlushFileBuffers Документ Windows API говорит:

[...] Обычно функции WriteFile и WriteFileEx записывают данные во внутренний буфер, который операционная система регулярно записывает на диск или канал связи. Функция FlushFileBuffers записывает всю буферизованную информацию для указанного файла в устройство или канал.

Из-за взаимодействия дискового кэширования внутри системы функция FlushFileBuffers может быть неэффективной при использовании после каждой записи на дисковое устройство, когда многие операции записи выполняются по отдельности.[...]

Создать файл документация:

[...] Когда приложение завершается с использованием дескриптора объекта, возвращенного CreateFile, используйте функцию CloseHandle, чтобы закрыть дескриптор. Это не только высвобождает системные ресурсы, но и может иметь более широкое влияние на такие вещи, как совместное использование файла или устройства и запись данных на диск. Подробности отмечаются в этой теме по мере необходимости.[...]

Больше информации о Кэширование файлов доступно здесь, Обратите внимание, что:

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

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

Johannes B. Latzel avatar
флаг cf
Я не думаю, что проблема в самом приложении. Я попробовал это, чтобы проверить гипотезу: а) я перезапустил сервер (чтобы все дескрипторы файлов закрывались или отбрасывались), б) я проверял время последней записи: штамп до времени шага а), в) я проверял свойства файла, г) я проверил время последней записи: штамп после шага а). Если бы это была проблема с записью/удалением данных приложения, метаданные после перезапуска уже должны были быть актуальными, но не были.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.