2008-09-29 5 views
2

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

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

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

ответ

1

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

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

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

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

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

+0

Это очень интересный момент, я намеревался сравнить различные способы написания файла, но, тем не менее, спасибо за ваше предложение. Что побудило меня попробовать этот метод, было сообщение в блоге (http://www.winasm.net/forum/index.php?showtopic=794) на winasm.net. – AnturCynhyrfus 2008-09-29 10:04:23

+0

Хотя вы можете быть правы в этом конкретном случае, это не ответ на вопрос. – 2011-01-13 22:47:13

2

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

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

1

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

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

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

1

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