Linux系統調用 - read

read()系統調用的原型:ssize_t read(int fd, void *buf, size_t count);

功能:從指定的文件描述符中讀取最多count個字節的數據到指定的buf中去。如果傳入的count是0,這個系統調用什麼都不幹,直接返回0。如果指定的count大於0,而且返回值也大於0,則表示函數執行成功,返回值表示成功讀取的字節數,同時被讀取的文件的當前數據指針會相應後移。如果返回值爲0,表示遇到了文件結尾。如果讀取失敗,read()會返回-1,並設置errno。

但是有時候,返回-1並不一定表示文件壞了讀不了了,比如:

如果在套接字上設置了O_NONBLOCK屬性(非阻塞),而當前套接字上又沒有數據可讀,那麼read()系統調用就會返回EAGAIN或者EWOULDBLOCK,表示暫時讀不到東西,稍後再來試吧。

再比如,雖然當前套接字是阻塞模式的,但是設置了發送或接收超時時間,那麼read()就會阻塞在套接字上等待數據過來,如果在超時時間內沒有拿到任何數據,那麼也會收到一個EAGAIN或者EWOULDBLOCK的errno,這時也應該稍後再來重新嘗試讀取。

另外還要注意,POSIX標準中並沒有規定在上面兩種情況下應該把errno設置爲EAGAIN還是EWOULDBLOCK,實現中設置這兩個錯誤代碼都是可以的,所以一個程序要具有更好的適用範圍,應該總是把這兩個errno放在一起檢查。

除此之外,還有一個errno,叫EINTR,表示在讀取過程中,在讀到數據之前被信號打斷了,這時也應該當做正常情況處理,信號處理程序執行完成之後,只要程序還能再回來,就應該當沒事一樣繼續正常的邏輯,重新讀一次。

其他一些錯誤代碼就要表示讀取失敗了,如EBADF,EFAULT,EINVAL,EIO等,具體就請參見幫助手冊吧。

用read()系統調用讀取本地磁盤設備上的文件時,通常可以認爲讀取速度是足夠快的,因此通常不會設置O_NONBLOCK標誌。在有些系統的實現上,設置會讓非阻塞標誌在處理本地磁盤文件是不生效。

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