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
);
参数
[] outpFile
文件指针将接收到打开的文件指针指向的指针。[] infilename
文件名。[] inmode
允许的访问类型。
返回值
如果成功,则为零 在失败的错误代码。 请参阅errno、_doserrno、_sys_errlist 和 _sys_nerr有关这些错误代码的详细信息。
错误条件
pFile |
filename |
mode |
返回值 |
内容pFile |
---|---|---|---|---|
NULL |
任何 |
任何 |
EINVAL |
不变 |
任何 |
NULL |
任何 |
EINVAL |
不变 |
任何 |
任何 |
空值 |
EINVAL |
不变 |
备注
通过打开的文件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 和 _sys_nerr.
Unicode 支持
fopen_s支持 Unicode 的文件流。 若要打开新的或现有的 Unicode 文件,请传递ccs标志,它指定所需的编码为 fopen_s::
fopen_s(&fp, "newfile.txt", "rw, ccs=encoding");
允许的值encoding的 UNICODE, UTF-8,和 UTF-16LE. 如果存在未指定值的 encoding, fopen_s使用 ANSI 编码。
如果该文件已经存在,并且已打开以进行读取或追加,字节顺序标记 (BOM),如果存在于文件中,将确定的编码。 物料清单编码优先通过编码由ccs标志。 ccs没有物料清单时存在,或如果该文件是新文件只使用编码。
备注
物料清单检测只适用于以 Unicode 模式 ; 打开的文件 也就是说,通过传递ccs标志。
下表总结了各种模式ccs标志提供给 fopen_s,并在该文件中的字节顺序标记。
编码用于基于 ccs 标志和物料清单
ccs标志 |
任何物料清单 (或新文件) |
物料清单: UTF-8 |
物料清单: 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 |
编写在 Unicode 模式下打开的文件可以自动写入其中的物料清单。
如果mode是"a, ccs=<encoding>", fopen_s第一次尝试打开该文件的读访问和写访问权限。 如果成功,此函数读取物料清单来确定编码的文件 ; 如果不成功,该函数将使用该文件的默认编码。 在任一情况下, fopen_s然后重新打开具有只写访问权限的文件。 (这适用于a模式下,不 a+。)
一般文本例程映射
TCHAR。H 例程 |
_UNICODE & 未定义 _MBCS |
定义 _MBCS |
定义 _UNICODE |
---|---|---|---|
_tfopen_s |
fopen_s |
fopen_s |
_wfopen_s |
字符串mode指定的访问请求时,该文件中,按如下所述的种类。
"r"
打开以进行读取。 如果该文件不存在,或无法找到, fopen_s调用失败。"w"
打开一个空文件以进行写入。 如果该文件存在,其内容将被销毁。"a"
打开以进行写入 (追加) 而不将新数据写入文件之前删除的 EOF 标记文件的末尾。 如果它不存在,则创建该文件。"r+"
将打开并读取和写入。 (该文件必须存在。"w+"
打开一个空的文件进行读写。 如果该文件存在,其内容将被销毁。"a+"
将打开并读取文件和追加。 追加操作包括删除 EOF 标记的新数据写入到文件并在编写完成后还原 EOF 标记之前。 如果它不存在,则创建该文件。
通过打开文件时"a"或 "a+"访问类型,所有写操作出现在文件的结尾。 可通过使用定位文件指针fseek或 rewind,但其始终移回至该文件的末尾之前任何写入,因此无法覆盖现有数据执行操作。
"a"模式下不会追加到该文件之前删除 EOF 标记。 追加发生后,MS-DOS TYPE 命令仅显示最原始的 EOF 标记的数据和追加到文件中没有任何数据。 "a+"模式不会追加到该文件之前删除的 EOF 标记。 后追加,MS-DOS TYPE 命令在文件中显示所有数据。 "a+"模式所需的追加到流文件,将终止通过使用 CTRL + Z EOF 标记。
当 "r+", "w+",或 "a+"指定访问类型,允许读取和写入。 (就说是打开"更新"文件)。 但是,当从阅读切换到书写,输入的操作必须会遇到 EOF 标记。 如果没有任何 EOF,则必须使用中间文件定位函数调用。 文件定位函数是 fsetpos, fseek,和 rewind. 从读数到写切换时,您必须使用中间调用fflush或文件定位函数。
除了上面的值中,下列字符可以包含在mode指定换行字符的转换模式:
- t
以文本形式打开 (翻译) 模式。 在此模式中,CTRL + Z 被解释为对输入文件结尾字符中。 要读取/写入与打开的文件中 "a+", fopen_s检查 CTRL + Z 结尾的文件并移除它,如果可能的话。 这是因为使用fseek和 ftell在结尾为 CTRL + Z,可能会导致文件移动 fseek文件末尾附近的不当行为。
此外,在文本模式下,回车 – 换行组合被翻译成在输入时,一个换行符) 和换行符转换为回车 – 换行组合输出上。 当 Unicode 流 i/o 函数操作文本模式 (默认值),源或目标流被认为是多字节字符的序列。 因此,Unicode 流输入函数将多字节字符转换为宽字符 (如果通过调用mbtowc函数)。 出于同样的原因,Unicode 流输出函数将宽字符转换为多字节字符 (如果通过调用wctomb函数)。
- b
打开二进制 (未翻译) 模式 ; 翻译涉及回车和换行字符不会显示。
如果t或 b中没有给出 mode,默认转换模式定义全局变量 _fmode。 如果t或 b将作为参数,函数将失败并返回前缀 NULL.
有关使用文本和二进制模式中 Unicode 和多字节流 i/o 的详细信息,请参阅文本和二进制模式文件 I/O 和 Unicode 文本和二进制模式中的流 I/O。
c
启用提交标记关联的 filename,以便文件缓冲区的内容将直接写入磁盘,如果任一 fflush或 _flushall调用。n
重置该提交标记关联的filename为"无约束" 这是默认设置。 它还重写全局提交标志,如果链接您的程序使用 COMMODE.OBJ。 全球提交标志默认设置是"无约束" 除非您显式链接您的程序使用 COMMODE。OBJ (请参阅 链接选项)。N
指定的文件不由子进程继承。S
指定的缓存优化的但不是限于,顺序访问磁盘。R
指定的缓存优化的但不是限于,随机访问磁盘。T
指定临时文件。 如有可能,它未被刷新到磁盘。D
指定临时文件。 最后的文件指针被关闭时,它将被删除。ccs=ENCODING
指定编码的字符集可用于此文件 (utf-8、 UTF-16LE 和 UNICODE)。 离开这未指定是否希望 ANSI 编码。
有效的字符mode中使用的字符串 fopen_s和 _fdopen对应于 oflag参数中使用 _ 打开 和 _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选项是 Microsoft 的扩展名 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 );
}