Как записать конец файла, открытого с помощью FILE_FLAG_NO_BUFFERING?

StackOverflow https://stackoverflow.com/questions/147996

  •  02-07-2019
  •  | 
  •  

Вопрос

Я использую 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.

Это было полезно?

Решение

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

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

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

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

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

Другие советы

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

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

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

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

Спасибо 'Майк Джи' за быстрый и точный ответ.И вам тоже спасибо»Габр', не надо заморачиваться SetEndOfFile вообще сейчас.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top