В Windows я должен использовать CreateFile или fopen, мобильность в стороне?

Каковы различия, и в том, какие случаи один или другой оказались бы выше в некотором роде?

9
задан CannibalSmith 14 June 2010 в 14:58
поделиться

4 ответа

Прежде всего, функция fopen может использоваться только для простых переносимых операций с файлами.

CreateFile с другой стороны может использоваться не только для операций с файлами, но и с каталогами (с использованием соответствующих опций), каналами и различными устройствами Windows.

CreateFile имеет множество дополнительных полезных переключателей, таких как FILE_FLAG_NO_BUFFERING, FILE_ATTRIBUTE_TEMPORARY и FILE_FLAG_SEQUENTIAL_SCAN, которые могут быть очень полезны в разных сценариях.

Можно использовать CreateFile с именем файла длиннее MAX_PATH символов. Это может быть важно для некоторых серверных приложений или тех, которые должны иметь возможность открыть любой файл (например, антивирусный сканер или приложение резервного копирования). Это обеспечивается с помощью семантики пространства имен, хотя у этого режима есть свои проблемы, такие как возможность фактически создать файл с именем ».. или L"xfeffx20xd9ab" (удачи в попытках удалить их позже).

CreateFile можно использовать в различных сценариях безопасности. Я имею в виду не только использование атрибутов безопасности. Если текущий процесс имеет SE_BACKUP_NAME или SE_RESTORE_NAME привилегии (как обычно имеют администраторы) и включить эту привилегию, можно использовать CreateFile для открытия любого файла, а также файла, к которому у вас нет доступа через дескриптор безопасности.

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

Существуют также другие применения функции, которые подробно описаны в соответствующей статье MSDN.

Поэтому я могу резюмировать: только если у вас есть жесткие требования к переносимости или если вам нужно передать FILE* в какую-то внешнюю библиотеку, тогда вы должны использовать fopen. Во всех остальных случаях я бы рекомендовал использовать CreateFile. Для достижения наилучших результатов я бы также посоветовал изучить Windows API специально, так как есть много функций, для которые вы можете найти хорошее применение.

UPDATED: Не имеет прямого отношения к вашему вопросу, но я также рекомендую вам взглянуть на транзакционные функции ввода-вывода, которые поддерживаются начиная с Windows Vista. Используя эту функцию, вы можете зафиксировать кучу операций с файлами, каталогами или реестром как одну транзакцию, которая не может быть прервана. Это очень мощный и интересный инструмент. Если вы не готовы использовать транзакционные функции ввода-вывода, можно начать с CreateFile и перенести приложение на транзакционный ввод-вывод позже.

9
ответ дан 4 December 2019 в 13:45
поделиться

CreateFile позволяет вам

  • Открыть файл для асинхронного ввода/вывода
  • Передать подсказки оптимизации, такие как FILE_FLAG_SEQUENTIAL_SCAN
  • Установить параметры безопасности и наследования без проблем с потоками

Они не возвращают один и тот же тип дескриптора, с объектом fopen/FILE вы можете вызвать другие функции времени выполнения, такие как fputs (а также преобразовать его в "родной" дескриптор файла)

1
ответ дан 4 December 2019 в 13:45
поделиться

Это действительно зависит от типа программы, которую вы пишете. Если предполагается, что он будет портативным, fopen облегчит вам жизнь. fopen вызовет CreateFile «за кадром».

Некоторые дополнительные параметры (управление кешем, управление доступом к файлам и т. Д.) Доступны только при использовании Win32 API (они зависят от дескриптора файла Win32, а не от указателя FILE в stdio ), поэтому, если вы пишете чистое приложение Win32, вы можете использовать CreateFile.

5
ответ дан 4 December 2019 в 13:45
поделиться

По возможности предпочитайте объектно-ориентированные обертки, поддерживающие RAII, такие как fstream или boost file IO objects.

Вам, конечно, должен быть важен режим совместного доступа, поэтому fopen() и STL недостаточно.

0
ответ дан 4 December 2019 в 13:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: