2009-11-01 74 views
161

是否有你想要Ç的fopen VS开放

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); 

在使用使用任何原因(除了语法之外的其它) C在Linux环境中?

+0

你的意思'fdopen'和'open'或'fopen'和'open'? – user7116 2009-11-01 21:53:35

+0

难道你不是指fopen,而不是fdopen? – Omnifarious 2009-11-01 21:53:40

+6

'fopen'是标准C库的一部分,'open'不是。编写便携式代码时使用'fopen'。 – Aziz 2009-11-01 21:53:47

回答

183

有四个主要原因使用fopen而不是open。

  1. fopen为您提供缓冲IO可能最终会比你与open做快了很多。
  2. fopen如果文件未以二进制模式打开,会执行行结束转换,如果您的程序已移植到非Unix环境,这可能非常有用。
  3. A FILE *可让您使用fscanf和其他stdio功能。
  4. 您的代码可能有一天需要移植到某个仅支持ANSI C的平台,并且不支持open函数。

在我看来,结束翻译的线条经常会比帮助你的方式困难得多,fscanf的解析非常薄弱,所以你不可避免地最终抛弃它,转而选择更有用的东西。

而大多数支持C的平台都有一个open函数。

这留下了缓冲问题。在主要依次读写文件的地方,缓冲支持非常有帮助,并且速度有了很大提高。但是,它可能会导致一些有趣的问题,即数据不会以文件形式出现在您希望的文件中。您必须在适当的时候记住fclosefflush

如果你正在做的目的,缓冲的有效性迅速下降。

当然,我的偏见是我倾向于使用套接字很多,并且事实上您确实想要做非阻塞IO(其中FILE *完全无法以任何合理方式支持),而没有缓冲,并且往往有复杂的分析要求,真正使我的看法变得色彩缤纷。

+3

我不会质疑你的经历,但我很乐意听到你对此有所阐述。对于什么样的应用程序,你觉得内置缓冲阻碍了你的工作?究竟是什么问题? – 2009-11-01 22:04:53

+0

没有看到最后一段。有效的点,恕我直言。尽管我可以说这个问题是关于文件IO的。 – 2009-11-01 22:06:26

+0

几乎所有不会流式传输IO的程序,最终都会寻找到文件中间。我应该更新我的回复以澄清。 – Omnifarious 2009-11-01 22:08:48

11

如果你有FILE *,您可以使用功能,如fscanffprintffgets等,如果你刚才的文件描述符,你有有限的(但可能更快)的输入和输出过程readwrite

40

open()是一个低级别的os调用。 fdopen()将os级文件描述符转换为C语言的更高级FILE抽象。 fopen()在后台调用open()并直接为您提供FILE指针。

使用FILE对象而不是原始文件描述符有几个优点,其中包括更易于使用,但也有其他技术优势,如内置缓冲。特别是缓冲通常会产生相当大的性能优势。

+2

使用缓冲的'f ...'版本的open有任何缺点吗? – LJM 2009-11-01 21:58:04

+3

@ L. Moser,是的,当你已经在缓冲数据时,因此额外的缓冲区会增加不必要的复制和内存开销。 – 2009-11-02 01:41:31

+5

其实还有其他的缺点。 'fopen()'在打开文件时不提供相同的控制级别,例如创建权限,共享模式等等。通常'open()'和变体提供了更多的控制,接近于操作系统实际提供的内容。 – 2009-11-07 11:54:01

10

除非您是使用open是实际性能优势的0.1%应用程序的一部分,否则确实没有理由不使用fopen。至于fdopen而言,如果您没有使用文件描述符,则不需要该呼叫。

棒与fopen和方法家族(fwritefreadfprintf等),你会很满意。同样重要的是,其他程序员会对你的代码感到满意。

6

使用打开,读,写意味着你不必担心信号interaptions。

如果呼叫是通过信号处理程序中断函数将返回-1 并设置errno为EINTR。

因此关闭文件的正确方法是

while (retval = close(fd), retval == -1 && ernno == EINTR) ; 
+4

对于'close',这取决于操作系统。在Linux,AIX和其他操作系统上执行循环是不正确的。 – strcat 2013-12-30 22:29:37

1

我换开()从fopen()函数我的应用程序,因为的fopen是造成双读我每次跑的fopen函数fgetc时间。双倍读取破坏了我试图完成的事情。 open()似乎是按照你所要求的。

-1

打开使用的fopen
之前,我们可以读(或写)的信息从(到)磁盘,我们必须打开该文件上的文件的文件。打开我们称之为函数fopen的文件。

1.firstly it searches on the disk the file to be opened. 
2.then it loads the file from the disk into a place in memory called buffer. 
3.it sets up a character pointer that points to the first character of the buffer. 

如此的fopen功能行为的方式
有一些原因而缓冲过程中,可能TIMEDOUT。所以在比较fopen(高级I/O)到开放(低级别I/O)系统调用时,它比更快更合适

+0

比fopen打开得快吗? – obayhan 2016-12-07 07:48:45

+0

是的,** open **是系统调用,它比fopen快 - 比较@obayhan – prashad 2017-04-11 12:33:49

4

open()是一个系统调用而具体到基于Unix的系统,它返回一个文件描述符。您可以使用另一个系统调用write()写入文件描述符。
fopen()是ANSI C函数调用返回一个文件指针,它是移植到其他操作系统。我们可以使用fprintf写入文件指针。

在Unix中:
可以使用得到的文件描述符文件指针:
fP = fdopen(fD, "a");
您可以通过使用得到文件指针文件描述符:
fD = fileno (fP);

4

的open()将在每个fopen()函数家庭功能的端部被调用。打开()是一个系统调用和fopen()函数由库用C提供为包装函数为用户容易使用

20

的fopen的VS开放

1)fopen库功能open系统调用

2)fopen提供缓冲IO其更快比较open这是非缓冲

3)fopen便携式open便携式是开放环境中的特定)。

4)fopen返回指向FILE结构(FILE *)的指针; open返回一个标识该文件的整数。

5)A FILE *使您能够使用fscanf和其他stdio函数。

+1

'open'是POSIX标准,所以它非常便携 – Spookbuster 2017-10-05 13:22:42

1

还取决于需要什么样的标志,以打开。关于书写和阅读的用法(和可移植性),应该使用f *,如上所述。

但是,如果基本上要指定比标准标志的更多(如RW和附加标志),你将不得不使用一个平台特定的API(如POSIX开)或抽象这些细节的库。 C标准没有任何这样的标志。

例如,你可能想打开一个文件,只有当它退出。如果您不指定创建标志,则该文件必须存在。如果您添加独占来创建,则只会在文件不存在时才创建该文件。还有更多。

例如在Linux系统有一个LED接口通过的sysfs露出。它通过文件显示led的亮度。以0-255范围内的字符串书写或读取数字。当然,你不想创建该文件,只有在存在的情况下才写入。现在很酷的事情:使用fdopen来使用标准调用来读/写这个文件。