В Windows я должен использовать CreateFile или fopen, кроме переносимости? - PullRequest
9 голосов
/ 14 июня 2010

В чем различия, и в каких случаях тот или иной вариант окажется в некотором роде лучшим?

Ответы [ 4 ]

9 голосов
/ 14 июня 2010

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

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

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

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

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

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

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

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

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

5 голосов
/ 14 июня 2010

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

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

1 голос
/ 14 июня 2010

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

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

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

0 голосов
/ 15 июня 2010

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

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

...