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视频教程》
以上是linux eof是什麼意思的詳細內容。更多資訊請關注PHP中文網其他相關文章!