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


fopen_s, _wfopen_s

Открывает файл. В этих версиях fopen, _wfopen усовершенствована безопасность, как описано в разделе Функции безопасности в 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
    Filename.

  • [входящий] mode
    Тип разрешенного доступа.

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

Нуль, если успешно; код ошибки при неудаче. Дополнительные сведения об этих кодах ошибок см. в разделе errno, _doserrno, _sys_errlist, and _sys_nerr.

Условия возникновения ошибки

pFile

filename

mode

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

СодержимоеpFile

NULL

any

any

EINVAL

unchanged

any

NULL

any

EINVAL

unchanged

any

any

NULL

EINVAL

unchanged

Заметки

Файлы, открытые fopen_s и _wfopen_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 передается указатель на null, эти функции генерируют исключение недопустимого параметра, как описано в разделе Проверка параметров.

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

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

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

fopen_s(&fp, "newfile.txt", "rw, ccs=encoding");

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

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

Примечание

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

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

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

Флаг ccs

Нет метки BOM (или новый файл)

BOM: UTF-8

BOM: UTF-16

UNICODE

UTF-16LE

UTF-8

UTF-16LE

UTF-8

UTF-8

UTF-8

UTF-16LE

UTF-16LE

UTF-16LE

UTF-8

UTF-16LE

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

Если mode — a, ccs=<encoding>, то fopen_s сначала пытается открыть файл с правами на чтение и доступ. Если это завершается успешно, функция считывает метку BOM, чтобы определить кодировку для файла; если операция завершается сбоем, функция использует для файла кодировку по умолчанию. В любом случае fopen_s затем снова открывает файл с правами только на запись. (Это актуально только для режима a, а не a+.)

Универсальное текстовое сопоставление функций

Подпрограмма TCHAR.H

_UNICODE & _MBCS не определены

_MBCS определено

_UNICODE определено

_tfopen_s

fopen_s

fopen_s

_wfopen_s

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

  • "r"
    Открывает для чтения. Если файл не существует или его невозможно найти, вызов fopen_s завершается ошибкой.

  • "w"
    Открывает пустой файл для записи. Если файл существует, его содержимое удаляется.

  • "a"
    Открывается для записи в конце файла (добавление) без удаления маркера в конце файла перед записью новых данных в файл. Создает файл, если он не существует.

  • "r+"
    Открывает для чтения и записи. (Файл должен существовать.)

  • "w+"
    Открывает пустой файл для чтения и записи. Если файл существует, его содержимое удаляется.

  • "a+"
    Открывается для чтения и добавления. При добавлении операция включает в себя удаление маркера конца файла перед записью новых данных в файл и восстановление маркера конца файла после завершения записи. Создает файл, если он не существует.

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

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

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

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

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

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

  • b
    При открытии в двоичном (непреобразованном) режиме преобразования, включающие символы возврата каретки и перевода строки, подавляются.

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

Дополнительные сведения о использовании текстового и бинарного режимов в юникоде и многобайтовом потоковом вводе-выводе см. в разделах Text and Binary Mode File I/O и Unicode Stream I/O in Text and Binary Modes.

  • c
    Включите флажок фиксации для связанного объекта filename, чтобы содержимое файлового буфера записывалось непосредственно на диск при вызове fflush или _flushall.

  • n
    Сбросьте флажок фиксации для связанного объекта filename, задайте для него значение "без фиксации". Это значение по умолчанию. Оно также переопределяет глобальный флаг фиксации при соединении программы с COMMODE.OBJ. Значение по умолчанию глобального флага фиксации — "без фиксации", если только программа не связана явно с файлом COMMODE.OBJ (см. Параметры ссылок).

  • N
    Указывает, что файл не наследуется дочерними процессами.

  • S
    Указывает, что кэширование оптимизировано для последовательного доступа с диска, но не ограничивается им.

  • R
    Указывает, что кэширование оптимизировано для случайного доступа с диска, но не ограничивается им.

  • T
    Определяет файл как временный. По возможности он не сбрасывается на диск.

  • D
    Определяет файл как временный. Он удаляется, если закрывается последний указатель файла.

  • ccs=ENCODING
    Задает набор кодированных символов, которые требуется использовать (UTF-8, UTF-16LE, and UNICODE) для этого файла. Не указывайте никакое значение, если требуется использовать кодировку ANSI.

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

Символы в строке режима

Эквивалентное значение 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

Нет

S

_O_SEQUENTIAL

R

_O_RANDOM

T

_O_SHORTLIVED

D

_O_TEMPORARY

ccs=UNICODE

_O_WTEXT

ccs=UTF-8

_O_UTF8

ccs=UTF-16LE

_O_UTF16

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

Требования

Функция

Обязательный заголовок

fopen_s

<stdio.h>

_wfopen_s

<stdio.h> или <wchar.h>

Дополнительные сведения о совместимости см. в разделе Совместимость во введении.

Библиотеки

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

Параметры c, nи t mode для fopen_s и _fdopen представляют собой расширения Майкрософт и не должны использоваться, если требуется обеспечить переносимость ANSI.

Пример

// 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" does not 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+" );
   if( err == 0 )
   {
      printf( "The file 'data2' was opened\n" );
   }
   else
   {
      printf( "The file 'data2' was not opened\n" );
   }

   // Close stream if it is not 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 );
}
  

Эквивалент в .NET Framework

См. также

Ссылки

Потоковый ввод-вывод

fclose, _fcloseall

_fdopen, _wfdopen

ferror

_fileno

freopen, _wfreopen

_open, _wopen

_setmode