Мне нужно создать новый дескриптор файла, чтобы любые операции записи в этот дескриптор немедленно записывались на диск.
Дополнительная информация: дескриптор будет унаследованным STDOUT дочернего процесса, поэтому мне нужно, чтобы любой вывод этого процесса был немедленно записан на диск.
Изучая документацию CreateFile
, флаг FILE_FLAG_WRITE_THROUGH
выглядел именно так, как мне нужно:
Операции записи не пройдут
любой промежуточный кеш они пойдут
непосредственно на диск.
Я написал очень простую тестовую программу, и она не работает.
Я использовал флаг CreateFile, затем использовал WriteFile(myHandle,...)
в длинном цикле, записывая около 100 МБ данных за 15 секунд. (Я добавил Sleep()
).
Затем я настроил профессиональную среду мониторинга, состоящую из непрерывного нажатия «F5» в проводнике. Результаты: файл остается на 0 КБ, затем переходит на 100 МБ к моменту окончания тестовой программы.
Затем я попытался вручную очистить файл после каждой записи с помощью FlushFileBuffers(myHandle)
. Это делает наблюдаемый размер файла хорошим и стабильным, как и ожидалось.
Мой вопрос: разве FILE_FLAG_WRITE_THROUGH
не сделал бы это без ручной очистки файла? Я что-то пропустил?
В программе «реального мира» я не могу сбросить файл, потому что у меня нет никакого контроля над дочерним процессом, который его использует.
Также есть флаг FILE_FLAG_NO_BUFFERING
, который я не могу использовать по той же причине - нет контроля над процессом, использующим дескриптор, поэтому я не могу вручную выровнять записи, как этого требует флаг. *
EDIT:
Я сделал отдельный проект специально для наблюдения за изменением размера файла. Он использует класс .NET FileSystemWatcher
. Я также пишу меньше данных - всего около 100 КБ.
Вот вывод. Проверьте секунды в метках времени.
Версия «встроенных без буферов»:
25.11.2008 7:03:22 PM: 10230 bytes added.
25.11.2008 7:03:31 PM: 10240 bytes added.
25.11.2008 7:03:31 PM: 10240 bytes added.
25.11.2008 7:03:31 PM: 10240 bytes added.
25.11.2008 7:03:31 PM: 10200 bytes added.
25.11.2008 7:03:42 PM: 10240 bytes added.
25.11.2008 7:03:42 PM: 10240 bytes added.
25.11.2008 7:03:42 PM: 10240 bytes added.
25.11.2008 7:03:42 PM: 10240 bytes added.
25.11.2008 7:03:42 PM: 10190 bytes added.
... и версия «принудительного (ручного) сброса» (FlushFileBuffers()
вызывается каждые ~ 2,5 секунды):
25.11.2008 7:06:10 PM: 10230 bytes added.
25.11.2008 7:06:12 PM: 10230 bytes added.
25.11.2008 7:06:15 PM: 10230 bytes added.
25.11.2008 7:06:17 PM: 10230 bytes added.
25.11.2008 7:06:19 PM: 10230 bytes added.
25.11.2008 7:06:21 PM: 10230 bytes added.
25.11.2008 7:06:23 PM: 10230 bytes added.
25.11.2008 7:06:25 PM: 10230 bytes added.
25.11.2008 7:06:27 PM: 10230 bytes added.
25.11.2008 7:06:29 PM: 10230 bytes added.