linux eof一般指檔案末尾;EOF是一個計算機術語,為End Of File的縮寫,在作業系統中表示資料源無更多的資料可讀取,在Linux中,在新的一行的開頭,按下「Ctrl+D」,就代表EOF。
本教學操作環境:linux5.9.8系統、Dell G3電腦。
linux eof是什麼意思?
EOF是一個計算機術語,為End Of File的縮寫,在作業系統中表示資料源無更多的資料可讀取。在linux下,一般指檔案末尾。
怎麼通過 EOF 來判斷程式是否讀取到了檔案末尾?
Linux 系統一個非常重要的思想就是:一切皆檔案。不管是標準輸入,檔案系統中的普通文字檔案,還是網路流都可以看做是檔案,都可以通過 read/write 函數進行讀寫操作。因此,不同的檔案型別,判斷是否讀取到檔案末尾的方式也就有所不同,下面就按照
普通文字檔案
標準輸入檔案(stdin)
socket 流檔案
這三類檔案來介紹判斷它們是否讀取到檔案末尾的方法。
普通文字檔案
這裡的普通檔案指的是我們平時在通過檔案管理器所能看到那些文字檔案,它存在於 Linux 中的檔案系統中,並且檔案的大小是固定的。
對於這種檔案,Linux 系統判斷普通文字檔案是否讀取到檔案末尾的方法是:read 函數會對所開啟的檔案維護一個讀取指標,然後根據這個指標跟檔案開始位置的指標值相減得到一個相對於檔案開始位置的偏移位元組數,最後通過這樣一個偏移位元組數和檔案本身的大小進行一個比較,如果相對於檔案開始位置的偏移位元組數大於檔案本身的大小,那麼就返回一個 EOF 常數,說明此時已經讀取到檔案末尾了。
所以,按照上面這樣寫法,如果一個檔案含有n個字元,那麼while迴圈的內部操作會執行n+1次。所以,最保險的寫法是像下面這樣:
int c = fgetc(fp);
while (c != EOF) {
do something;
c = fgetc(fp);
}
if (feof(fp)) {
printf("\n End of file reached.");
} else {
printf("\n Something went wrong.");
}
登入後複製
標準輸入檔案
標準輸入檔案(stdin)它對應的是外設鍵盤輸入,而在 Linux 系統中它被抽象成一個檔案,準確地說是一個流檔案。這種檔案和上面普通文字檔案最大的區別就是它的檔案大小是不固定的,它就像是一個水管的進水端,可以在任何時候都可以接收輸入。
正是因為標準輸入檔案這種流式的特點,決定了無法通過前面提到那種比較檔案大小方法來判斷是否讀取到了檔案末尾。因此,Linux 系統判斷標準輸入檔案是否讀取到檔案末尾的方法是:設定一個特殊的輸入標記來表示檔案末尾,而在Linux 系統中這個標記就是組合鍵Ctrl+D,當系統捕獲到這個組合鍵時,就讓 r read 函數返回一個 EOF 常數,告知程式已經讀取到標準檔案的末尾了。
socket 流檔案
socket 流檔案和標準輸入檔案類似都是流式檔案,並且它是從網路上進行資料讀取,所以上面兩種判斷檔案是否讀取到末尾的方法都不適用於 socket 流檔案。
那麼使用者端程序怎麼判斷伺服器端程序是否已經寫完所有資料?
在 socket 流檔案中,當用戶端程序通過 read 函數讀取遠端伺服器端程序傳送過來的資料時,使用的是阻塞I/O的方式進行讀取的。只要使用者端和伺服器端之間的連線沒有斷開,如果伺服器端沒有向 socket 寫入資料,那麼使用者端的讀操作就會阻塞,直到伺服器端中寫入了新的資料。
如果伺服器端程序關閉了socket連線,那麼使用者端會接收到伺服器端傳送過來的一個 TCP 協定的 FIN 封包,然後使用者端程序中原本阻塞著等待接收伺服器端程序資料的 read函數此時就會被喚醒,返回一個值 0。這跟我們前面提到兩種檔案讀到檔案末尾返回 EOF(值為-1)的情況有點差別,所以在程式中從 socket 進行讀取操作時,判斷資料流結束的標誌不是 -1 而是 0。
Linux中,在新的一行的開頭,按下Ctrl-D,就代表EOF(如果在一行的中間按下Ctrl-D,則表示輸出」標準輸入」的快取區,所以這時必須按兩次Ctrl-D);Windows中,Ctrl-Z表示EOF。(順便提一句,Linux中按下Ctrl-Z,表示將該程序中斷,在後臺掛起,用fg命令可以重新切回到前臺;按下Ctrl-C表示終止該程序。)
那麼,如果真的想輸入Ctrl-D怎麼辦?這時必須先按下Ctrl-V,然後就可以輸入Ctrl-D,系統就不會認為這是EOF訊號。Ctrl-V表示按」字面含義」解讀下一個輸入,要是想按」字面含義」輸入Ctrl-V,連續輸入兩次就行了。
所以,一個簡單的從 socket 檔案讀取資料的樣例程式碼,通常是下面這樣的:
char recvline[MAX_LINE_LENGTH];
int read_count;
while ((read_count = read(sock_fd, recvline, MAX_LINE_LENGTH)) > 0)
{
printf("%s\n", "String received from server: ");
fputs(recvline, stdout);
}
登入後複製
總結
所以,一定要記住這樣一個概念:EOF 是一個常數而不是一個字元!。
推薦學習:《》
以上就是linux eof是什麼意思的詳細內容,更多請關注TW511.COM其它相關文章!