Мне нужно создать новый дескриптор файла, чтобы любые операции записи с этим дескриптором немедленно записывались на диск.
Дополнительная информация: дескриптор будет унаследованным STDOUT дочернего процесса, поэтому мне нужно, чтобы любой результат этого процесса сразу записывался на диск.
Изучая документацию CreateFile
, флаг FILE_FLAG_WRITE_THROUGH
выглядел как именно то, что мне нужно:
Операции записи не пройдут любой промежуточный кеш, они пойдут непосредственно на диск.
Я написал очень базовую тестовую программу и, ну, она не работает.
Я использовал флаг в CreateFile, а затем использовал WriteFile(myHandle,...)
в длинном цикле, написав около 100 МБ данных примерно за 15 секунд. (Я добавил несколько Sleep()
).
Затем я создал профессиональную среду мониторинга, состоящую из непрерывного удара "F5" в проводнике. Результаты: файл остается на 0 КБ, а затем переходит на 100 МБ примерно в момент окончания тестовой программы.
Следующее, что я пробовал, - это вручную очистить файл после каждой записи, FlushFileBuffers(myHandle)
. Это делает наблюдаемый размер файла хорошим и стабильным, как и ожидалось.
Мой вопрос в том, должен ли FILE_FLAG_WRITE_THROUGH
сделать это без вручную, очистив файл? Я что-то упускаю?
В программе "real world" я не могу очистить файл, потому что у меня нет никакого контроля над дочерним процессом, который его использует.
Также существует флаг FILE_FLAG_NO_BUFFERING
, который я не могу использовать по той же причине - без контроля над процессом, использующим дескриптор, поэтому я не могу вручную выровнять записи, как требуется этим флагом.
EDIT:
Я сделал отдельный проект специально для просмотра того, как изменяется размер файла. Он использует класс .NET FileSystemWatcher
. Я также пишу меньше данных - всего около 100 кБ.
Здесь вывод. Проверьте секунды на отметках времени.
Версия встроенного no-buffers:
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.