Буферизация файлов в Windows


В этой статье рассматриваются различные аспекты прикладного управления буферизацией файлов, также известной как небуферизованный ввод-вывод файлов (I/O). Буферизация файлов обычно обрабатывается системой за кулисами и считается частью кэширования файлов в операционной системе Windows, если не указано иное. Хотя термины кэширование и буферизация иногда используются взаимозаменяемо, в этой статье термин буферизация используется специально в контексте объяснения того, как взаимодействовать с данными, которые не кэшируются (буферизуются) системой, где они в противном случае в значительной степени находятся вне прямого контроля приложений пользовательского режима.

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

Примечание. Эта информация о выравнивании применяется к вводу-выводу на таких устройствах, как файлы, поддерживающие поиск и концепцию указателей положения файлов (или смещений). Для устройств, которые не ищут, таких как именованные каналы или коммуникационные устройства, отключение буферизации может не требовать какого-либо конкретного выравнивания. Любые ограничения или эффективность, которые могут быть получены путем выравнивания в этом случае, зависят от базовой технологии.

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

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

Требования к выравниванию и доступу к файлам

Как уже говорилось ранее, приложение должно соответствовать определенным требованиям при работе с файлами, открытыми с помощью FILE_FLAG_NO_BUFFERING. Применяются следующие особенности:

  • Размеры доступа к файлам, включая необязательное смещение файла в ПЕРЕКРЫВАЮЩЕЙСЯ структуре, если оно указано, должны быть для числа байтов, которое является целым числом, кратным размеру сектора тома. Например, если размер сектора составляет 512 байт, приложение может запросить чтение и запись 512, 1024, 1536 или 2048 байт, но не 335, 981 или 7171 байт.
  • Адреса буферов доступа к файлам для операций чтения и записи должны быть выровнены по физическим секторам, что означает выравнивание по адресам в памяти, которые являются целыми числами, кратными размеру физического сектора тома. В зависимости от типа диска это требование может не выполняться.
Разработчикам приложений следует обратить внимание на появление на рынке новых типов устройств хранения данных с размером сектора физических носителей 4096 байт. Отраслевое название этих устройств - "расширенный формат". Поскольку могут возникнуть проблемы совместимости с непосредственным введением 4096 байт в качестве единицы адресации для носителя, временное решение совместимости состоит в том, чтобы ввести устройства, которые эмулируют обычное 512-байтовое секторное запоминающее устройство, но предоставляют доступную информацию об истинном размере сектора с помощью стандартных команд ATA и SCSI.

В результате такой эмуляции, по сути, существуют два размера секторов, которые разработчикам необходимо будет понять:

  • Логический сектор: единица измерения, используемая для адресации логических блоков носителя. Мы также можем думать о нем как о самой маленькой единице записи, которую может принять хранилище. Это и есть "подражание".
  • Физический сектор: блок, для которого операции чтения и записи в устройство выполняются за одну операцию. Это единица атомной записи, и то, что небуферизованный ввод-вывод должен быть выровнен, чтобы иметь оптимальные характеристики производительности и надежности.
Большинство современных API-интерфейсов Windows, таких как IOCTL_DISK_GET_DRIVE_GEOMETRY и GetDiskFreeSpace, возвращают логический размер сектора, но физический размер сектора может быть получен с помощью управляющего кода IOCTL_STORAGE_QUERY_PROPERTY с соответствующей информацией, содержащейся в элементе BytesPerPhysicalSector в структуре STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR.

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

Windows Server 2003 и Windows XP: структура STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR недоступна. Он был представлен вместе с Windows Vista и Windows Server 2008.

Поскольку адреса буферов для операций чтения и записи должны быть выровнены по секторам, приложение должно иметь прямой контроль над распределением этих буферов. Одним из способов выравнивания буферов по секторам является использование функции VirtualAlloc для выделения буферов. Рассмотреть следующее:

  • VirtualAlloc выделяет память, выровненную по адресам, которые являются целыми числами, кратными размеру страницы системы. Размер страницы составляет 4096 байт для систем x64 и x86 или 8192 байта для систем на базе Itanium.
  • Размер сектора обычно составляет от 512 до 4096 байт для устройств хранения данных прямого доступа (жестких дисков) и 2048 байт для компакт-дисков.
  • Размеры страниц и секторов имеют степень 2.
Поэтому в большинстве случаев память, выровненная по страницам, также будет выровнена по секторам, поскольку случай, когда размер сектора больше размера страницы, встречается редко.

Другой способ получить выровненные вручную буферы памяти-это использовать функцию _aligned_malloc из библиотеки среды выполнения C.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегистатьи IT, windows, файл, буферизация, файловая система




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




Урок 32. Обработка исключений C#
Что такое HLR запрос
Хитрости прохождения проверки оптимизации для мобильных