C fopen 与 open
- 2024-10-09 09:11:00
- admin 原创
- 87
问题描述:
您是否还有什么理由(除了句法原因)想要使用
FILE *fdopen(int fd, const char *mode);
或者
FILE *fopen(const char *path, const char *mode);
而不是
int open(const char *pathname, int flags, mode_t mode);
在Linux环境中使用C时?
解决方案 1:
其中,fdopen
与其他 不同。如果您先调用,然后想要 ,fdopen
则可以使用。 如果您可以选择直接调用,则这样做毫无意义。 在某些情况下,您将无法完全按照自己的意愿行事,但这超出了本问题的讨论范围。open
`FILE *fopen
fopen`
因此,我们就假装fdopen
它不存在并继续回答问题。
fopen
使用而不是有四个主要原因open
。
fopen
为您提供缓冲IO,其速度可能比您使用的速度快得多open
。fopen
如果文件不是以二进制模式打开的,则进行行尾转换,如果您的程序被移植到非 Unix 环境,这将非常有用(尽管世界似乎正在趋向于仅 LF(除了 IETF 基于文本的网络协议,如 SMTP 和 HTTP 等))。A
FILE *
使您能够使用fscanf
和其他 stdio 功能。您的代码可能有一天需要移植到其他仅支持 ANSI C 而不支持该
open
功能的平台。
以我的观点(和经验)来看,行尾翻译往往会给你带来麻烦而不是帮助,并且的解析fscanf
非常弱,你最终不可避免地会将其丢弃,而选择更有用的东西。
并且大多数支持C的平台都有一个open
函数。
剩下的就是缓冲问题。在主要按顺序读取或写入文件的地方,缓冲支持确实很有帮助,可以大大提高速度。但它可能会导致一些有趣的问题,即数据不会在您期望它出现时出现在文件中。您必须记住在适当的时间fclose
这样做。fflush
如果您正在进行搜索(又名fsetpos
或fseek
第二种搜索,其以符合标准的方式使用起来稍微有点棘手),缓冲的实用性就会迅速下降。
当然,我的偏见是我倾向于大量使用套接字,而事实上你真正想要做的是非阻塞 IO(FILE *
完全无法以任何合理的方式支持)而没有任何缓冲,并且经常有复杂的解析要求,这确实影响了我的看法。
解决方案 2:
open()
是一个低级的操作系统调用。fdopen()
将操作系统级别的文件描述符转换为 C 语言的高级 FILE 抽象。在后台fopen()
调用open()
并直接为您提供 FILE 指针。
使用 FILE 对象而非原始文件描述符有几个优点,包括更易于使用,还有其他技术优势,例如内置缓冲。特别是缓冲通常会带来相当大的性能优势。
解决方案 3:
fopen
`open`与 C 语言相比
fopen
是库函数,而open
是系统调用。fopen
提供缓冲 IO,与非缓冲open
IO相比,其速度可能更快。fopen
可移植,但open
不可移植(open
特定于环境)。fopen
返回一个指向结构的指针FILE
(FILE *
),同时open
返回一个标识文件的整数。A
FILE *
使您能够使用fscanf
和其他stdio.h
功能。
解决方案 4:
除非您是 0.1% 的应用程序的一部分,其中 usingopen
确实可以带来性能优势,否则真的没有理由不使用fopen
。 就此fdopen
而言,如果您不使用文件描述符,则不需要该调用。
坚持使用fopen
及其方法系列(fwrite
、fread
、fprintf
等),您会非常满意。同样重要的是,其他程序员也会对您的代码感到满意。
解决方案 5:
如果您有FILE *
,则可以使用诸如fscanf
、fprintf
和fgets
等函数。如果您只有文件描述符,则您有有限的(但可能更快)的输入和输出例程read
,write
等等。
解决方案 6:
open()
`write()`是一个系统调用,特定于基于 Unix 的系统,它返回一个文件描述符。您可以使用另一个系统调用写入文件描述符。
fopen()
是一个 ANSI C 函数调用,它返回一个文件指针,它可以移植到其他操作系统。我们可以使用写入文件指针fprintf
。
在 Unix 中:
你可以使用以下命令从文件描述符获取文件指针:
fP = fdopen(fD, "a");
您可以使用以下方法从文件指针获取文件描述符:
fD = fileno (fP);
解决方案 7:
使用打开、读取、写入意味着您必须担心信号交互。
如果调用被信号处理程序中断,函数将返回 -1 并将 errno 设置为 EINTR。
因此关闭文件的正确方法是
while (retval = close(fd), retval == -1 && ernno == EINTR) ;
解决方案 8:
我将应用程序的 fopen() 更改为 open() ,因为每次运行 fopen fgetc 时,fopen 都会导致双重读取。双重读取会破坏我试图完成的任务。 open() 似乎只是按照你的要求去做。
解决方案 9:
open()将在每个fopen()系列函数的末尾被调用。open ()是一个系统调用,fopen()由库提供,作为包装函数,方便用户使用
解决方案 10:
还取决于需要打开哪些标志。就写入和读取(以及可移植性)的用途而言,应该使用 f*,如上所述。
但是,如果基本上想要指定标准标志以外的标志(如 rw 和 append 标志),则必须使用特定于平台的 API(如 POSIX open)或抽象这些细节的库。C 标准没有任何此类标志。
例如,您可能希望仅当文件存在时才打开它。如果您未指定创建标志,则文件必须存在。如果您将独占添加到创建,则只有在文件不存在时才会创建它。还有更多。
例如,在 Linux 系统上,有一个通过 sysfs 公开的 LED 接口。它通过文件公开 LED 的亮度。将数字作为字符串写入或读取,范围从 0 到 255。当然,您不想创建该文件,并且只在该文件存在时写入。现在很酷的事情是:使用 fdopen 通过标准调用读取/写入此文件。
解决方案 11:
我认为这个问题已经得到充分回答,但这是一个有趣的问题,所以让我发表一下我的看法。我认为open()
它更接近操作系统内核,并且比fopen()
函数级别更低。open()
函数是 POSIX 标准的一部分,在某些情况下可能更可取。如果您正在开发 Linux 驱动程序或想要在 POSIX 兼容系统上执行非阻塞 IO,您将需要使用open()
而不是fopen()
。但是,如果您想要的只是在 Linux 和 Windows 上都可以使用的跨平台文件 I/O,fopen()
这将是更好的选择。
解决方案 12:
使用以下方式打开文件fopen
在我们读取(或写入)磁盘上的文件信息之前,我们必须打开该文件。要打开文件,我们调用函数fopen()
。
fopen()
在磁盘中搜索要打开的文件。然后,它将文件从磁盘加载到内存中称为缓冲区的位置。
最后,它设置一个字符(
char
)指针,指向缓冲区的第一个字符。
有时,在缓冲过程中fopen()
可能会超时。
因此,当将fopen()
库调用(高级 i/o)与open()
(低级 i/o)系统调用进行比较时,使用open()
比更快、更合适fopen()
。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件