Как вы пишете конец файла, открытого с FILE_FLAG_NO_BUFFERING? - PullRequest
3 голосов
/ 29 сентября 2008

Я использую VB6 и Win32 API для записи данных в файл, эта функция предназначена для экспорта данных, поэтому производительность записи на диск является ключевым фактором в моих соображениях. Поэтому я использую опции FILE_FLAG_NO_BUFFERING и FILE_FLAG_WRITE_THROUGH при открытии файла с вызовом CreateFile.

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

Я могу использовать SetEndOfFile, однако для этого требуется, чтобы я закрыл файл и снова открыл его, не используя FILE_FLAG_NO_BUFFERING. Я видел, как кто-то говорил о NtSetInformationFile, но я не могу найти, как использовать и объявить это в VB6. SetFileInformationByHandle может делать именно то, что я хочу, однако это доступно только в Windows Vista, мое приложение должно быть совместимо с предыдущими версиями Windows.

Ответы [ 4 ]

2 голосов
/ 29 сентября 2008

Я считаю, что SetEndOfFile - единственный способ.

И я согласен с Майком Дж., Что вы должны сравнить свой код с FILE_FLAG_NO_BUFFERING и без него. Буферизация файлов Windows на современных ОС чертовски эффективна.

2 голосов
/ 29 сентября 2008

Я не уверен, но ВЫ уверены, что настройка FILE_FLAG_NO_BUFFERING и FILE_FLAG_WRITE_THROUGH даст вам максимальную производительность?

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

Для такой процедуры экспорта данных, как вы описываете, разрешение операционной системе буферизовать ваши данные, вероятно, приведет к ЛУЧШЕЙ производительности, поскольку записи будут планироваться в соответствии с другими действиями на диске, а не заставлять диск возвращаться к регистрировать каждую запись.

Почему бы вам не протестировать свой код без этих опций? Оставьте в логике дополнения 0 байт, чтобы сделать ее честной проверкой.

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

1 голос
/ 15 июня 2011

Для файла размером 1 ГБ буферизация Windows, вероятно, будет быстрее, особенно если делать много маленьких операций ввода-вывода. Если вы имеете дело с файлами, которые намного больше доступной оперативной памяти, и делаете IO для больших блоков, то флаги, которые вы устанавливаете, будут давать лучшую пропускную способность (до 3 раз быстрее для многопоточных и / или случайных IO больших блоков).

1 голос
/ 29 сентября 2008

Ну, я поражен! Использование буферизации Windows вместо того, чтобы делать все самостоятельно, НАМНОГО быстрее. Я выписывал файл размером 1 Гб для тестирования, используя свой собственный буфер, а параметры FILE_FLAG_NO_BUFFERING и FILE_FLAG_WRITE_THROUGH заняли в среднем 21,146 секунды, без этих настроек и с использованием буфера Windows среднее время сократилось до 13,53 секунды, это больше На 30% быстрее!

Примечание для себя: не нужно заново изобретать колесо. ; -)

Спасибо ' Mike G ' за ваш быстрый и точный ответ. А также благодаря вам габр , теперь вам не нужно беспокоиться о SetEndOfFile.

...