流和文件的區別

前面介紹的Linux下的文件編程所涉及的操作方式都是不帶緩衝的I/O,因爲每次調用相應的函數比如說read、write等對文件進行操作的時候都會調用內核的系統調用,由於每次都要通過內核對文件進行操作,所以操作效率比較低,對於流編程來說,首先對文件所映射的流進行操作,然後分階段將相應的數據寫入文件,極大地提高了相應的操作效率。Linux也提供了很多流操縱庫函數,稱爲標準I/O庫,是ISO C的組成部分。

文件的I/O函數都是針對文件描述符進行操作的,比如說當調用open或者其他函數打開一個文件,返回一個文件的描述符fd,然後針對這個fd進行後續的I/O操作,由於需要多次反覆調用對應的系統調用,效率低是自然的。

而流I/O函數的操作是圍繞流(Stream)進行的,當使用流I/O庫打開或者創建一個文件時,可以使一個流和一個文件結合,接下來的操作就是對流進行讀寫、定位等,最後關閉即可。


上圖可以看出流和文件,帶緩衝和不帶緩衝是相對而言的。對於不帶緩衝的文件I/O操作也不是直接對文件進行的,只是在用戶空間沒有緩衝區,所以是不帶緩衝的I/O,但是對於Linux內核來說,還是進行了緩衝。當用戶調用不帶緩衝的IO函數寫數據到文件時,即對磁盤存儲區進行讀寫,Linux內核會先將數據寫入到內核中的緩衝存儲區。比如說,緩衝存儲區的長度是50字節,調用write函數進行寫操作時,如果每次寫入10個字節,則需要調用5次write函數,而此時數據還是在內核的緩衝區中的,並沒有寫入到磁盤。當50個字節已經寫滿的時候才進行實際的IO操作,把數據寫入到磁盤中。

帶緩衝的IO則是在用戶空間中建立了另外一個緩衝區,即流緩衝區,假設流緩衝區的長度也是50個字節,當調用對應的寫入庫函數時會將數據寫入到這個流緩存裏面,然後再一次性進入內核緩存區,此時再使用系統調用將數據寫入到文件,從而減少了系統調用

總之,對於不帶緩衝的I/O,將數據寫入磁盤的過程是:數據→內核緩衝區→磁盤;而對於帶緩衝的I/O其過程是:數據→流緩衝區→內核緩衝區→磁盤

流操作函數對象不是文件描述符,而是一個流緩衝區。當打開一個流時,返回一個指向FILE對象的指針。該對象是一個結構體,包含了管理這個流所需要的所有信息,比如說用於實際I/O的文件描述符、指向流緩存的指針、緩存的長度、當前緩存中的字符數、出錯標誌等。在實際的應用中,用戶只需要知道爲了引用一個流,需要將FILE指針作爲參數傳遞給對應的函數即可。用戶可以簡單地把流看做一塊由操作系統分配的內存緩衝區,在該緩衝區中存放了文件對應的數據。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章