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 );
}