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/OUnicode 文本和二进制模式中的流 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 );
}
  

.NET Framework 等效项

请参见

参考

流 I/O

fclose、_fcloseall

_fdopen、_wfdopen

ferror

_fileno

freopen、_wfreopen

_open、_wopen

_setmode