Это действительно по замыслу. Это давнее поведение операционных систем Microsoft/IBM, которое также можно найти в 32-битной OS/2, 16-битной OS/2, PC-DOS, MS-DOS, а также DR-DOS (также известной как Novell DOS или OpenDOS).
Поведение состоит в том, что запись каталога в файле только обновляется, показывая правильную метку времени последнего изменения, размер и информацию о выделении в списке каталога, когда запись таблицы системных файлов для файла закрыта. Запись SFT закрывается, когда закрыты все открытые дескрипторы во всех процессах, которые ссылаются на нее. Программы, которые находятся в процессе загрузки "сотен MiB", еще не закрыли свои дескрипторы открытых файлов. Поэтому их SFT-записи не закрыты. Таким образом, записи каталога не обновляются.
Если один или несколько дополнительных дескрипторов файла были созданы с помощью DosDupHandle
, внутренние буферы для файла не записываются на диск, и его запись в каталоге не обновляется , пока не будет вызван DosClose
для всех дескрипторов.
- «Закрытие файлов».
OS/2 Warp: Руководство и справочник по программированию управляющей программы . Корпорация IBM.
На однозадачных MS/PC/DR-DOS это несколько трудно наблюдать, хотя это можно наблюдать под DesqView, Windows 3.x в 386 Enhanced Mode, TASKMAX
и так далее. На многозадачной ОС /2 это можно было регулярно и легко наблюдать.
Одной из менее приятных особенностей этого поведения было (на томах FAT), что грязное завершение работы до закрытия дескриптора файла привело бы к тому, что CHKDSK
увидит файл нулевого размера и обрежет все загруженное до сих пор.
Это было поведение, совершенно отличное от UNIX, где можно было наблюдать рост файла по мере его роста с помощью ls -l
потому что команда ls
смотрела на i-узел (в оперативной памяти и в актуальном состоянии) для метаданных файла, а не на запись каталога (которая в собственных файловых системах UNIX не имеет информации о размере и дате). DOS, OS/2 и Windows NT также увеличивают размер файла. Блоки данных выделяются для файла, запись SFT отслеживает размер файла, структуры, такие как f-узел (в томах HPFS), обновляются, и, как вы заметили, свободное пространство тома уменьшается. Просто невозможно увидеть, с помощью dir
или чего-либо еще, что сообщает о содержимом записи каталога, растущий файл.
Ситуация с Windows NT и NTFS очень похожа на ситуацию с OS/2 и DOS. (Номенклатура изменилась, что немного смущает новичка. Если в DOS и OS/2 имеются записи в таблице системных файлов, на которые ссылаются дескрипторы файлов в отдельных процессах, в Windows NT есть файловые объекты, на которые ссылаются дескрипторы в отдельных процессах.) По иронии судьбы, это больше похоже на поведение старых операционных систем IBM/Microsoft, начиная с Windows NT 6.0, где поведение было изменено. "Новое" поведение NTFS заключается в том, что записи каталога для файла, хранящиеся в каждом из каталогов, которые имеют ссылку на файл и используются при перечислении каталога из Win32 (с FindFirstFile
/FindNextFile
), обновляются только тогда, когда файл объект для файла закрыт, в то время как метаданные, прикрепленные к самому файлу, не видимые из списка каталогов (и доступные только через вызовы, такие как GetFileInformationByHandle
), обновляются как файл.
Чтобы уменьшить риск грязного завершения работы и увидеть, как увеличивается размер файла при записи в него, использовался простой прием. Вы тоже все еще можете использовать его.
Запись каталога в файле обновляется всякий раз, когда запись таблицы системных файлов для него закрывается, а запись SFT закрывается, когда закрывается последний дескриптор открытого файла в любом процессе, который ссылается на него. Это не должен быть дескриптор, открытый или используемый процессом записи в файл. Можно использовать все, что открывает файл (создает отдельную запись SFT) и закрывает его снова. Это может быть что-то простое, например, команда type
запущенная в другой консоли / сеансе:
type file > nul
По иронии судьбы, Total Commander's Lister сделал бы именно это, каждый раз, когда вы использовали его для просмотра содержимого файла во время его записи. Если бы вы заметили это, вы бы здесь спросили, почему Lister Total Commander волшебным образом "исправили" ваш каталог. И ответом было бы то, что в Total Commander нет ничего особенного. Все, что открывалось и закрывалось отдельно, имело бы тот же эффект.
Для полноты заметим, что имелись системные вызовы, которые загружающая программа могла использовать для обновления записи каталога по мере продвижения. OS/2 имеет DosBufReset
например. Тем не менее, эти системные вызовы также очищают кэш диска, что не обязательно то, что нужно. Открытие файла во второй раз, а затем закрытие этого дескриптора файла не очищает кэш диска.