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
);
参数
[out] pFile
要接收指向已打开的文件的指针的指针。[in] filename
文件名。[in] mode
允许的访问类型。
返回值
零,如果成功;在失败的错误代码。 请参见 errno、_doserrno、_sys_errlist和_sys_nerr 有关这些错误代码的更多信息。
错误状态
pFile |
filename |
mode |
返回值 |
pFile内容 |
---|---|---|---|---|
NULL |
any |
any |
EINVAL |
保持不变。 |
any |
NULL |
any |
EINVAL |
保持不变。 |
any |
any |
NULL |
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 文件,请通过指定所需的编码到 fopen_s的 ccs 标志:
fopen_s(&fp, "newfile.txt", "rw, ccs=encoding");
encoding 允许的值为 UNICODE、UTF-8和 UTF-16LE。 如果该值不为 encoding指定,fopen_s 使用 ANSI 编码。
如果文件用于读取或追加已存在且已打开,请在文件的字节顺序标记 (BOM),如果有,确定编码。 BOM 编码优先于由 ccs 标志指定的编码。 只有使用 ccs 编码,当 BOM 不存在或,如果文件是一个新文件。
备注
BOM 检测仅适用于 Unicode 模式打开的文件,即通过将 ccs 标志。
下表总结了给定 fopen_s 以及在文件的字节顺序标记的各种 ccs 标志的模式。
编码使用了基于 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 |
为编写中打开在 Unicode 模式匹配的文件对它们自动编写的 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"
为编写打开隐藏文件 (追加) 结束时,如果不移除 EOF 标记在编写新数据之前到文件。 如果不存在,创建文件。"r+"
用于读取和写入打开。 (文件必须存在。)"w+"
打开读取和写入的空文件。 如果文件存在,销毁其内容。"a+"
用于读取和追加打开。 追加的操作包括 EOF 标记中删除,新的数据写入文件之前,然后恢复 EOF 标记,在编写完成之后。 如果不存在,创建文件。
使用 "a" 或 "a+" 访问类型时,在打开文件时,所有写入操作发生在文件末尾。 使用 fseek 或 rewind,文件指针可以被重新定位,但是,它始终被移动到文件尾,在所有写入操作之前,以便现有数据无法重写。
"a" 模式不在追加前移除 EOF 添加到文件。 在追加发生后,MS-DOS 类型命令显示数据到原始 EOF 标记和不追加到文件所需的任何数据。 "a+" 模式在追加前移除 EOF 添加到文件。 在追加后,MS-DOS 类型命令文件中显示所有数据。 "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 进行标志“NO-使”。这是默认设置。 如果使用 COMMODE.OBJ,链接程序它还重写全局进行标记。 全局标志使默认值为“NO-使”,除非您使用 COMMODE.OBJ 显式链接程序 (请参见 LINK选项)。N
指定文件未由子进程继承。S
指定缓存中优化对,但是,不受限制为,顺序访问从磁盘。R
指定缓存中优化对,但是,不受限制为,随机访问从磁盘。T
指定文件。临时。 如果可能,它不会刷新到磁盘。D
指定文件。临时。 在最后一个文件指针关闭时,则会将其删除。ccs=ENCODING
指定该代码的字符集为此文件使用 (UTF-8、UTF-16LE 和 UNICODE)。 如果需要 ANSI 编码,请将此未指定。
用于 fopen_s 和 _fdopen 的 mode 字符串的有效字符对应于用于 _open 和 _sopen的 oflag 参数,如下所示。
在模式字符串的字符 |
_open的/_sopen等效的 oflag 值 |
---|---|
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和 tmode 选项是 fopen_s 和 _fdopen 的 Microsoft 扩展,不应使用 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 等效项
System::IO::FileStream::FileStream