簡體   English   中英

read() 系統調用將實際讀取的數據量

[英]Amount of data read() syscall will actually read

假設我有一個文件,該文件的文件描述符在 EOF 之前剩余超過 n 個字節,並且我調用了 n 個字節的 read() 系統調用。 該函數是否保證將 n 個字節讀入緩沖區? 還是可以少讀一點?

read系統調用保證讀取您要求的盡可能多的字符,除非它不能。 但事實證明,有太多的例外——很多情況下它無法讀取你要求的那么多字符——以至於它基本上最終是最安全的假設任何給定的read調用可能不會讀取為您要求的許多字符。 我相信始終牢記這一點來編寫代碼是一種很好的做法。

我系統上的手冊頁說

如果描述符引用一個在文件結束前剩余那么多字節的普通文件,則系統保證讀取請求的字節數,但沒有其他情況。

因此,如果它不是一個普通文件,或者它是一個普通文件但沒有足夠的字符,那么您得到的將比您要求的少。 但是在您詢問的情況下,是的,您應該保證獲得與您要求的一樣多的字符。

盡管如此,如果您發現自己在假設read據稱保證讀取所請求的字符數與承認它可能返回更少的字符之間做出選擇,我總是會編寫代碼以假設它可能返回更少。 也就是說,如果你有一個類似的電話

r = read(fd, buf, n);

假設如果r大於 0,它必須正好是n ,通常不會有太多收獲。 您的代碼必須能夠處理r < n情況,以便在幾乎處於文件末尾時它會正常運行,因此除非您想要有兩種不同的代碼路徑(一種用於“正常”讀取,另一種用於last read),你不妨寫一段代碼,處理r < n情況,讓它一直運行。

(此外,正如 Zan Lynx 在評論中提醒的那樣,不要讓代碼注意到r < n ,並從中推斷文件結束即將到來。等待r == 0再決定你在文件結尾。)

您可以自己從手冊頁閱讀它:

在 Linux 上, read() (和類似的系統調用)將最多傳輸0x7ffff000 (2,147,479,552)個字節,返回實際傳輸的字節數。 (在 32 位和 64 位系統上都是如此。)

因此,即使您有足夠的 RAM 等等,您也無法一次性讀取完整尺寸的 DVD 映像——然而,這也不是明智之舉; 要訪問如此大的文件, mmap會更好。


除此之外,可能會傳遞一個信號,這可能導致EINTR退出和緩沖區內容不確定。

錯誤

[...]

  • EINTR在讀取任何數據之前調用被信號中斷; 見信號(7)。

該函數是否保證將 n 個字節讀入緩沖區? 還是可以少讀一點?

不,即使您的文件在結束前有超過n個字節, read(fd, buf, n)函數也不能保證將n個字節讀入緩沖區然后返回n 它可以讀取更少並返回小於n的正值。

請參閱https://man7.org/linux/man-pages/man2/read.2.html 上的Linux 手冊頁

返回值

如果此數字小於請求的字節數,則不是錯誤; 例如,這可能是因為現在實際可用的字節較少(可能是因為我們接近文件尾,或者因為我們正在從管道或終端讀取),或者因為 read() 被一個信號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM