说明

fopen()函数将打开名称为路径名指向的字符串的文件,并将流与其关联。

参数模式指向以以下序列之一开头的字符串(可能后面跟其他字符,如下所述):

r
打开文本文件以供阅读。流位于文件的开头。
r+
开放供阅读和写作。流位于文件的开头。
w
将文件截断为零长度或创建要写入的文本文件。流位于文件的开头。
w+
开放供阅读和写作。如果该文件不存在,则创建该文件,否则该文件将被截断。流位于文件的开头。
a
打开以进行追加(在文件末尾写入)。如果文件不存在,则创建该文件。流位于文件的末尾。
a+
打开以进行读取和追加(在文件末尾写入)。如果文件不存在,则创建该文件。输出始终附加在文件末尾。 POSIX对使用此模式时的初始读取位置保持沉默。对于glibc,读取的初始文件位置在文件的开头,但是对于Android / BSD / MacOS,读取的初始文件位置在文件的结尾。

模式字符串还可以包含字母aqbaq作为最后一个字符,或者作为上述两个字符的字符串中任意一个字符之间的字符。严格来说,这是为了与C89兼容,并且无效。在所有符合POSIX的系统(包括Linux)上,都会忽略aqbaq。 (其他系统可能会以不同的方式对待文本文件和二进制文件,如果对二进制文件进行I / O并且希望将程序移植到非UNIX环境,则添加aqbaq可能是个好主意。)

有关mode的glibc扩展的详细信息,请参见下面的注释。

任何创建的文件将具有S_IRUSR模式。 S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH(0666),由进程的umask值修改(请参见umask(2))。

读写可以以任何顺序混合在读/写流上。请注意,除非输入操作遇到文件结尾,否则ANSI C要求在输出和输入之间插入文件定位功能。 (如果不满足此条件,那么允许读操作返回除最近操作以外的写操作的结果。)因此,最好将fseek(3)或fgetpos(3 )在此类流上进行读写操作之间的操作。此操作可能是明显的禁止操作(如在fseek(...,0L,SEEK_CUR)中因其同步副作用而被调用)。

以追加模式(模式的第一个字符)打开文件会导致对该流的所有后续写入操作在文件末尾发生,就像在调用之前一样:

fseek(stream, 0, SEEK_END);

与流相关联的文件描述符就像通过调用带有以下标志的open(2)一样被打开:

fopen()modeopen()标志 rO_RDONLY wO_WRONLY | O_CREAT | O_TRUNC aO_WRONLY | O_CREAT | O_APPEND r + O_RDWR w + O_RDWR | O_CREAT | O_TRUNC a + O_RDWR | O_CREAT | O_APPEND

fdopen()

fdopen()函数将流与现有文件描述符fd关联。流的模式(值" r"," r +"," w"," w +"," a"," a +"之一)必须与文件描述符的模式兼容。将新流的文件位置指示符设置为属于fd的文件位置指示符,并清除错误和文件结束指示符。模式" w"或" w +"不会导致文件被截断。文件描述符未复制,并且在由fdopen()创建的流关闭时将关闭。将fdopen()应用于共享内存对象的结果是不确定的。

freopen()

freopen()函数打开名称为路径名指向的字符串的文件,并将流指向的流与该文件关联。原始流(如果存在)被关闭。就像在fopen()函数中一样使用mode参数。

如果pathname参数为空指针,则freopen()将流的模式更改为mode中指定的模式;也就是说,freopen()重新打开与流关联的路径名。在C99标准中添加了有关此行为的规范,该规范说:

在这种情况下,如果对freopen()的调用成功,则无需关闭与流相关的文件描述符。由实现定义,允许哪些模式更改(如果有)以及在什么情况下允许。

freopen()函数的主要用途是更改与标准文本流(stderr,stdin或stdout)关联的文件。

名称

fopen,fdopen,freopen-流打开功能

返回值

成功完成fopen(),fdopen()和freopen()后,将返回FILE指针。否则,将返回NULL并将errno设置为指示错误。

语法

#include <stdio.h>

FILE *fopen(const char *pathname, const char *mode);

FILE *fdopen(int fd, const char *mode);

FILE *freopen(const char *pathname, const char *mode, FILE *stream);

glibc的功能测试宏要求(请参阅feature_test_macros(7)):

fdopen():_ POSIX_C_SOURCE

错误说明

EINVAL
提供给fopen(),fdopen()或freopen()的模式无效。

fopen(),fdopen()和freopen()函数也可能会失败,并为例程malloc(3)指定的任何错误设置errno。

fopen()函数也可能会失败,并为例程open(2)指定的任何错误设置errno。

fdopen()函数也可能会失败,并为例程fcntl(2)指定的任何错误设置errno。

freopen()函数也可能会失败,并为例程open(2),fclose(3)和fflush(3)指定的任何错误设置errno。

备注

Glibc notes

GNU C库允许在mode中指定的字符串具有以下扩展名:

c(since glibc 2.3.3)
请勿使open操作或后续的读写操作成为线程取消点。 fdopen()会忽略此标志。
e(since glibc 2.7)
使用O_CLOEXEC标志打开文件。有关更多信息,请参见open(2)。 fdopen()会忽略此标志。
m(since glibc 2.3)
尝试使用mmap(2)而不是I / O系统调用(read(2),write(2))访问文件。当前,仅尝试为打开的文件尝试使用mmap(2)。
x
以独占方式打开文件(如open(2)的O_EXCL标志)。如果文件已经存在,则fopen()失败,并将errno设置为EEXIST。 fdopen()会忽略此标志。

除上述字符外,fopen()和freopen()在模式下还支持以下语法:

,ccs = string

给定的字符串被用作编码字符集的名称,并且流被标记为面向宽方向。此后,内部转换函数将I / O与字符集字符串进行相互转换。如果未指定.ccs = string语法,则流的宽方向由第一个文件操作确定。如果该操作是宽字符操作,则将流标记为面向宽方向,并加载转换为编码字符集的函数。

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/

属性

有关本节中使用的术语的说明,请参见attribute(7)。

InterfaceAttributeValue
fopen(),fdopen(),freopen()Thread safetyMT-Safe
FOPEN - Linux手册页

Linux程序员手册 第3部分
更新日期: 2019-05-09

BUGS

在模式下解析单个标志字符(即," ccs"规范之前的字符)时,fopen()和freopen()的glibc实现将在模式下检查的字符数限制为7(或者在2.14之前的glibc版本中)到6,这还不足以包含" rb + cmxe"之类的可能规范。 fdopen()的当前实现在模式下最多解析5个字符。

遵循规范

fopen(),freopen():POSIX.1-2001,POSIX.1-2008,C89,C99。

fdopen():POSIX.1-2001,POSIX.1-2008。

另外参见

open(2),fclose(3),fileno(3),fmemopen(3),fopencookie(3),open_memstream(3)

日期:2019-08-20 18:00:20 来源:oir作者:oir