fopen, _wfopen

打开文件。 这些功能的更安全版本可用;请参见 fopen_s, _wfopen_s

FILE *fopen( 
   const char *filename,
   const char *mode 
);
FILE *_wfopen( 
   const wchar_t *filename,
   const wchar_t *mode 
);

参数

  • filename
    文件名。

  • mode
    启用的类型访问。

返回值

这些函数都返回一个指向打开文件。 一个空指针值指示错误。 如果 filename 或 mode 是 NULL 或为空字符串,这些函数触发无效参数处理程序,在 参数验证所述。 如果执行允许继续,这些函数返回 NULL 并将 errno 到 EINVAL。

有关更多信息,请参见errno、_doserrno、_sys_errlist和_sys_nerr

备注

fopen 函数打开由 filename指定的文件。 _wfopen 是 fopen的宽字符版本;为 _wfopen 的参数是宽字符字符串。 否则,_wfopen 和 fopen 具有相同的行为。 使用 _wfopen 没有对文件流的代码的字符集的效果。

fopen 接受有效在文件系统中的路径;fopen 接受涉及映射的网络驱动器的 UNC 路径和路径,只要执行的系统代码对共享访问或映射的驱动器在执行时。 当构造 fopen的路径时,请确保驱动器、路径或网络共享将在执行环境。 可以使用斜杠 (/) 或斜杠 (\) 作为内容分隔符在路径。

始终检查返回值查看指针是否为空,则无法对文件的任何其他操作。 如果发生错误,全局变量 errno 设置并可用于获取特定错误信息。 有关更多信息,请参见errno、_doserrno、_sys_errlist和_sys_nerr

Unicode 支持

fopen 支持 Unicode 文件流。 若要打开 Unicode 文件,如下所示请通过指定所需的编码到 fopen,的 ccs 标志。

fopen(&fp, "newfile.txt", "rw, ccs=encoding");

encoding 允许的值为 UNICODE、UTF-8和 UTF-16LE。

如果文件用于读取或追加已存在且已打开,字节顺序标记 (BOM),则为;在文件中存在,确定编码。 BOM 编码优先于由 ccs 标志指定的编码。 只有使用 ccs 编码,当 BOM 不存在或文件是一个新文件。

备注

BOM 检测仅适用于即 Unicode 模式打开的文件 (通过 ccs 标志)。

下表汇总了各种 ccs 标志使用给定 fopen 和字节顺序标记文件中的模式。

编码使用了基于 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 首先尝试打开包含两个的文件读取和写入。 如果已成功,函数读取 BOM 确定文件的编码;如果此操作失败,该功能为文件使用默认值编码。 无论如何都 fopen,然后将重新打开包含只读访问文件。 (这会应用于 a 仅模式,不适用于 a+ 模式。)

一般文本例程映射

TCHAR.H 实例

未定义的_UNICODE & _MBCS

定义的_MBCS

定义的_UNICODE

_tfopen

fopen

fopen

_wfopen

字符字符串 mode 如下指定请求文件,已访问。

  • "r"
    用于读取打开。 如果文件不存在或无法找到,fopen 调用失败。

  • "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 被解释为输入的相对 EOF 字符。 使用 "a+"如果可能,在用于读取/写入中打开的文件,fopen 检查 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 编码,保留未指定。

mode 的有效字符字符串用于 fopen,并 _fdopen 如下对应于 oflag 参数用于 _open_sopen

在模式字符串的字符

_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

<stdio.h>

_wfopen

<stdio.h> 或 <wchar.h>

有关兼容性的更多信息,请参见 兼容性

c、n、t、S、R、T和 Dmode 选项是 fopen 和 _fdopen 的 Microsoft 扩展,不应使用 ANSI 可移植性需位置。

示例

以下过程打开两个文件。 它使用 fclose 结束第一文件和 _fcloseall 关闭所有剩余的文件。

// crt_fopen.c
// compile with: /W3
// 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 )
{
   int numclosed;

   // Open for read (will fail if file "crt_fopen.c" does not exist)
   if( (stream  = fopen( "crt_fopen.c", "r" )) == NULL ) // C4996
   // Note: fopen is deprecated; consider using fopen_s instead
      printf( "The file 'crt_fopen.c' was not opened\n" );
   else
      printf( "The file 'crt_fopen.c' was opened\n" );

   // Open for write 
   if( (stream2 = fopen( "data2", "w+" )) == NULL ) // C4996
      printf( "The file 'data2' was not opened\n" );
   else
      printf( "The file 'data2' was opened\n" );

   // Close stream if it is not NULL 
   if( stream)
   {
      if ( fclose( stream ) )
      {
         printf( "The file 'crt_fopen.c' was not closed\n" );
      }
   }

   // All other files are closed: 
   numclosed = _fcloseall( );
   printf( "Number of files closed by _fcloseall: %u\n", numclosed );
}
  

下面的过程中使用 Unicode 编码的文本方式创建一个文件 (或被一,如果存在)。 然后编写两个字符串到文件中并关闭文件。 输出是一_wfopen_test.xml 的文件,包含从输出部分的数据。

// crt__wfopen.c
// compile with: /W3
// This program creates a file (or overwrites one if
// it exists), in text mode using Unicode encoding.
// It then writes two strings into the file
// and then closes the file.
 
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <wchar.h>

#define BUFFER_SIZE 50

int main(int argc, char** argv)
{
wchar_t str[BUFFER_SIZE];
size_t  strSize;
FILE*   fileHandle;

    // Create an the xml file in text and Unicode encoding mode.
    if ((fileHandle = _wfopen( L"_wfopen_test.xml",L"wt+,ccs=UNICODE")) == NULL) // C4996
    // Note: _wfopen is deprecated; consider using _wfopen_s instead
    {
        wprintf(L"_wfopen failed!\n");
        return(0);
    }

    // Write a string into the file.
    wcscpy_s(str, sizeof(str)/sizeof(wchar_t), L"<xmlTag>\n");
    strSize = wcslen(str);
    if (fwrite(str, sizeof(wchar_t), strSize, fileHandle) != strSize)
    {
        wprintf(L"fwrite failed!\n");
    }

    // Write a string into the file.
    wcscpy_s(str, sizeof(str)/sizeof(wchar_t), L"</xmlTag>");
    strSize = wcslen(str);
    if (fwrite(str, sizeof(wchar_t), strSize, fileHandle) != strSize)
    {
        wprintf(L"fwrite failed!\n");
    }

    // Close the file.
    if (fclose(fileHandle))
    {
        wprintf(L"fclose failed!\n");
    }
    return 0;
}

.NET Framework 等效项

请参见

参考

流I/O

多字节字符序列的说明

fclose, _fcloseall

_fdopen, _wfdopen

ferror

_fileno

freopen, _wfreopen

_open, _wopen

_setmode

_sopen, _wsopen