2009-11-01 78 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來使用標準調用來讀/寫這個文件。