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 等效项

请参见

参考

流I/O

fclose, _fcloseall

_fdopen, _wfdopen

ferror

_fileno

freopen, _wfreopen

_open, _wopen

_setmode