Поделиться через


fopen_s, _wfopen_s

Открывает файл. Эти версии имеют _wfopenулучшения безопасности, как описано в функциях fopenбезопасности в CRT.

Синтаксис

errno_t fopen_s(
   FILE** pFile,
   const char *filename,
   const char *mode
);
errno_t _wfopen_s(
   FILE** pFile,
   const wchar_t *filename,
   const wchar_t *mode
);

Параметры

pFile
Указатель на указатель на файл, который получает указатель на открытый файл.

filename
Имя файла, который необходимо открыть.

mode
Тип разрешенного доступа.

Возвращаемое значение

Возвращает нуль в случае успеха или код ошибки в случае неудачи. Дополнительные сведения об этих кодах ошибок см. в разделе errno, _doserrno_sys_errlistи _sys_nerr.

Условия ошибок

pFile filename mode Возвращаемое значение Содержимое pFile
NULL любое любое EINVAL без изменений
любое NULL любое EINVAL без изменений
любое любое NULL EINVAL без изменений

Замечания

_wfopen_s Функции fopen_s не могут открывать файл для общего доступа. Если необходимо предоставить общий доступ к файлу, использовать _fsopen или _wfsopen с соответствующей константой режима общего доступа, например использовать _SH_DENYNO для совместного использования чтения и записи.

Функция fopen_s открывает файл, указанный в filenameфайле. _wfopen_s — это версия расширенных fopen_s символов и аргументы _wfopen_s для строк с широкими символами. _wfopen_s и fopen_s ведет себя одинаково, в противном случае.

Функция fopen_s принимает пути, допустимые в файловой системе во время выполнения; UNC-пути и пути, в которых фигурируют сопоставленные сетевых диски, принимаются функцией fopen_s, если система, которая выполняет код, имеет доступ к общему или сетевому диску в момент выполнения. При построении путей для fopen_s убедитесь, что драйверы, пути или сетевые общие папки будут доступны в среде выполнения. Вы можете использовать косую черту (/) или обратные косые черты (\) в качестве разделителей каталогов в пути.

Эти функции проверяют свои параметры. Если pFile, filenameили mode является пустым указателем, эти функции создают недопустимое исключение параметров, как описано в проверке параметров.

Всегда проверяйте возвращаемое значение, чтобы узнать, выполнена ли функция успешно, прежде чем выполнять дальнейшие операции с файлом. Если возникает ошибка, возвращается код ошибки, а глобальная переменная errno устанавливается. Дополнительные сведения см. в разделе errno, _doserrno, _sys_errlist, и _sys_nerr.

По умолчанию глобальное состояние этой функции ограничивается приложением. Чтобы изменить его, ознакомьтесь с глобальным состоянием в CRT.

Поддержка Юникода

fopen_s поддерживает файловые потоки Юникода. Чтобы открыть новый или существующий файл Юникода, передайте ccs флаг, указывающий нужную кодировку fopen_s, например:

fopen_s(&fp, "newfile.txt", "w+, ccs=UNICODE");

Допустимые значения флагаccs: UNICODEи UTF-8UTF-16LE. Если для этого значения не указано ccs, fopen_s используется кодировка ANSI.

Если файл уже существует и открыт для чтения или добавления, то метка порядка байтов (BOM), если она присутствует в файле, определяет кодировку. Кодировка, заданная меткой BOM, имеет приоритет над кодировкой, заданной флагом ccs. Заданная флагом ccs кодировка используется, только если метка BOM отсутствует или речь идет о новом файле.

Примечание.

Обнаружение метки BOM применяется только к файлам, которые будут открываться в режиме Юникода (т. е. путем передачи флага ccs).

В следующей таблице приведены сведения о режимах для различных ccs значений флагов, которые предоставляются fopen_s и для boms в файле.

Кодировки, используемые на ccs основе флагов и BOM

Флагccs Нет метки BOM (или новый файл) BOM: UTF-8 BOM: UTF-16
UNICODE UTF-8 UTF-8 UTF-16LE
UTF-8 UTF-8 UTF-8 UTF-16LE
UTF-16LE UTF-16LE UTF-8 UTF-16LE

В файлы, открываемые для записи в режиме Юникода, метка BOM записывается автоматически.

Если mode имеет "a, ccs=UNICODE"значение , "a, ccs=UTF-8"или "a, ccs=UTF-16LE"fopen_s сначала пытается открыть файл с доступом на чтение и записью. Если эта операция завершается успешно, функция считывает метку BOM, чтобы определить кодировку для файла; если операция завершается сбоем, функция использует для файла кодировку по умолчанию. В любом случае fopen_s повторно открывает файл с доступом только для записи. (Это поведение применяется только к режиму a , а не a+к .)

Символьная строка mode указывает тип доступа, который запрошен для файла, следующим образом.

mode Открыть
"r" Открывает для чтения. Если файл не существует или не удается найти, вызов завершается ошибкой fopen_s .
"w" Открывает пустой файл для записи. Если указанный файл существует, его содержимое удаляется.
"a" Открывается для записи в конце файла (добавление) без удаления маркера в конце файла (EOF) перед записью новых данных в файл. Создает файл, если он не существует.
"r+" Открывает для чтения и записи. Файл должен существовать.
"w+" Открывает пустой файл для чтения и записи. Если файл существует, его содержимое удаляется.
"a+" Открывается для чтения и добавления. Операция добавления включает удаления маркера EOF перед записью новых данных в файл. Маркер EOF не восстанавливается после завершения записи. Создает файл, если он не существует.

Если файл открывается с использованием типа доступа "a" или "a+", все операции записи выполняются в конце файла. Указатель на файл может быть перемещен с помощью fseek или rewind, но он всегда перемещается обратно в конец файла перед выполнением любой операции записи, чтобы существующие данные не могли быть перезаписаны.

Режим "a" не удаляет маркер EOF перед добавлением в файл. После добавления команда MS-DOS TYPE отображает только данные до исходного маркера EOF, а не какие-либо данные, добавленные в файл. Перед добавлением в файл режим "a+" удаляет маркер конца файла. После добавления команда MS-DOS TYPE отображает все данные в файле. Этот "a+" режим необходим для добавления в потоковый файл, который завершается маркеромCTRL+ Z EOF.

"r+"Если указан тип доступа "w+", или "a+" тип доступа, разрешено чтение и запись. (Файл, как сообщается, открыт для "обновления".) Однако при переходе с чтения на запись входная операция должна возникнуть через маркер EOF. Если маркер EOF отсутствует, необходимо использовать промежуточный вызов функции размещения файлов. Функции позиционирования в файле — это fsetpos, fseek и rewind. При переходе от записи к чтению необходимо воспользоваться промежуточным вызовом либо функции fflush, либо функции позиционирования в файле.

Начиная с C11, можно добавить "x" "w" или "w+" вызвать сбой функции, если файл существует, а не перезаписывать его.

Помимо предыдущих значений, в него можно включить mode следующие символы, чтобы указать режим перевода для новых символов:

mode модификатор Режим перевода
t Откройте файл в текстовом (переведенном) режиме. Сочетания канала возврата каретки (CR-LF) превратятся в однострочные каналы (LF) для входных данных и символов LF превратятся в сочетания CR-LF для выходных данных. CTRL+Z интерпретируется как символ конца файла во входных данных.
b Откройте в двоичном (нетрансляционном) режиме; переводы, включающие символы канала каретки и строки, подавляются.

В режиме CTRL+преобразования текста Z интерпретируется как символ конца файла во входных данных. Если это возможно, для файлов, открытых для чтения и записи"a+", fopen_s проверяет наличиеCTRL+ Z в конце файла и удаляет его. Он удаляется из-за использования fseek и ftell перемещения в файл, который заканчивается CTRL+Z, может привести fseek к неправильному ведении в конце файла.

Кроме того, в текстовом режиме сочетания возврата и строки каретки (CRLF) превратятся в символы однострочного канала (LF) для входных данных, а символы LF переводятся в сочетания CRLF для выходных данных. Если функция ввода-вывода потока Юникода работает в текстовом режиме (по умолчанию) исходный или конечный поток рассматривается как последовательность многобайтовых символов. Функции потокового ввода Юникода преобразуют многобайтовые символы в широкие символы (как будто вызовом mbtowc функции). По той же причине выходные функции потока Юникода преобразуют расширенные символы в многобайтовые (как если бы для этого вызывалась функция wctomb ).

Если t или b нет mode, режим перевода по умолчанию определяется глобальной переменной _fmode. Если символ t или b указан как префикс аргумента, функция завершается с ошибкой и возвращает NULL.

Дополнительные сведения об использовании текстовых и двоичных режимов в Юникоде и многобайтовом потоке ввода-вывода см. в разделе "Текстовый и двоичный режим ввода-вывода" и потокового ввода-вывода Юникода в текстовых и двоичных режимах.

mode модификатор Поведение
c Включите флажок фиксации для связанного объекта filename , чтобы содержимое файлового буфера записывалось непосредственно на диск при вызове fflush или _flushall .
n Сброс флага фиксации для связанного filename с "no-commit". Этот флаг по умолчанию. Он также переопределяет глобальный флаг фиксации, если вы связываете программу с COMMODE.OBJ. Флаг глобальной фиксации по умолчанию — "без фиксации", если вы явно не связываете программу с COMMODE.OBJ (см. раздел "Параметры ссылки").
N Указывает, что файл не наследуется дочерними процессами.
S Указывает, что кэширование оптимизировано для последовательного доступа с диска, но не ограничивается им.
R Указывает, что кэширование оптимизировано для случайного доступа с диска, но не ограничивается им.
T Указывает файл, который не записывается на диск, если это не требуется.
D Указывает временный файл, который удаляется при закрытии последнего указателя файла.
ccs=UNICODE Указывает ЮНИКОД в качестве закодированного символа, используемого для этого файла. Не указывайте никакое значение, если требуется использовать кодировку ANSI.
ccs=UTF-8 Указывает UTF-8 в качестве закодированного символьного набора, используемого для этого файла. Не указывайте никакое значение, если требуется использовать кодировку ANSI.
ccs=UTF-16LE Указывает UTF-16LE в качестве закодированного символа, используемого для этого файла. Не указывайте никакое значение, если требуется использовать кодировку ANSI.

Допустимые символы строки, используемой mode fopen_s в и _fdopen соответствующие oflag аргументам, используемым в _open и _sopen, как показано ниже.

Символы в строке mode Эквивалентное значение oflag для _open/_sopen
a _O_WRONLY | _O_APPEND (обычно _O_WRONLY | _O_CREAT | _O_APPEND)
a+ _O_RDWR | _O_APPEND (обычно _O_RDWR | _O_APPEND | _O_CREAT)
R _O_RDONLY
r+ _O_RDWR
w _O_WRONLY (обычно _O_WRONLY | _O_CREAT | _O_TRUNC)
w+ _O_RDWR (обычно **_O_RDWR | _O_CREAT | _O_TRUNC)
b _O_BINARY
t _O_TEXT (переведено)
c нет
n нет
D _O_TEMPORARY
R _O_RANDOM
S _O_SEQUENTIAL
T _O_SHORTLIVED
ccs=UNICODE _O_WTEXT
ccs=UTF-8 _O_UTF8
ccs=UTF-16LE _O_UTF16

<a0/>, n, tTSRи D mode параметры — это расширения Майкрософт для fopen_s и _wfopen_s не должны использоваться, если требуется переносимость ANSI.

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

Относительно T и D:

  • T избегает записи файла на диск до тех пор, пока не требуется давление на память. Дополнительные сведения см. в разделе FILE_ATTRIBUTE_TEMPORARY "Константы атрибутов файла", а также в этой записи блога Только временный.
  • D указывает обычный файл, записанный на диск. Разница заключается в том, что он автоматически удаляется при закрытии. Вы можете объединить оба TD семантики.

Требования

Function Обязательный заголовок Заголовок C++
fopen_s <stdio.h> <cstdio>
_wfopen_s <stdio.h> или <wchar.h> <cstdio>

Дополнительные сведения о соответствии стандартам и соглашениях об именовании в библиотеке среды выполнения C см. в разделе "Совместимость".

Сопоставления подпрограмм универсального текста

<tchar.h> рутина _UNICODE и _MBCS не определен _MBCS Определенные _UNICODE Определенные
_tfopen_s fopen_s fopen_s _wfopen_s

Библиотеки

Все версии библиотек времени выполнения языка C.

Пример

// crt_fopen_s.c
// This program opens two files. It uses
// fclose to close the first file and
// _fcloseall to close all remaining files.

#include <stdio.h>

FILE *stream, *stream2;

int main( void )
{
   errno_t err;

   // Open for read (will fail if file "crt_fopen_s.c" doesn't exist)
   err  = fopen_s( &stream, "crt_fopen_s.c", "r" );
   if( err == 0 )
   {
      printf( "The file 'crt_fopen_s.c' was opened\n" );
   }
   else
   {
      printf( "The file 'crt_fopen_s.c' was not opened\n" );
   }

   // Open for write
   err = fopen_s( &stream2, "data2", "w+, ccs=UTF-8" );
   if( err == 0 )
   {
      printf( "The file 'data2' was opened\n" );
   }
   else
   {
      printf( "The file 'data2' was not opened\n" );
   }

   // Close stream if it isn't NULL
   if( stream )
   {
      err = fclose( stream );
      if ( err == 0 )
      {
         printf( "The file 'crt_fopen_s.c' was closed\n" );
      }
      else
      {
         printf( "The file 'crt_fopen_s.c' was not closed\n" );
      }
   }

   // All other files are closed:
   int numclosed = _fcloseall( );
   printf( "Number of files closed by _fcloseall: %u\n", numclosed );
}
The file 'crt_fopen_s.c' was opened
The file 'data2' was opened
Number of files closed by _fcloseall: 1

См. также

Потоковый ввод-вывод
fclose, _fcloseall
_fdopen, _wfdopen
ferror
_fileno
freopen, _wfreopen
_open, _wopen
_setmode