| 場景 | 文件 InputStream | Socket InputStream |
|---|---|---|
| 數據源 | 有限、靜態、可預知大小 | 動態、流式、對端決定何時結束 |
| read() 返回 -1 | 讀到文件末尾(EOF) | 對端**關閉輸出流**(`shutdownOutput()` 或 Socket 關閉) |
| 無數據時行為 | 立即返回 -1(EOF) | **阻塞等待**,直到有數據到達或對端關閉 |
// 服務端處理客戶端請求
InputStream in = socket.getInputStream();
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) != -1) { // 陷阱!
process(buf, len);
}
// 這裡永遠執行不到,除非客戶端關閉連接
**原因**:客戶端發完一個請求後**不關閉連接**(保持長連接等待響應),服務端 `read()` 一直阻塞等待下一個請求或連接關閉,導致無法跳出循環處理業務、發送響應。
// 伪代碼:長度前綴協議
DataInputStream dis = new DataInputStream(socket.getInputStream());
while (true) {
int length = dis.readInt(); // 讀取 4 字節長度
byte[] body = new byte[length];
dis.readFully(body); // 精確讀取消息體
process(body);
sendResponse();
}



**Socket 流無 EOF 概念**,`read()` 返回 -1 **唯一條件是對端關閉輸出**。長連接場景下,**必須引入應用層協議幀**界定消息邊界,否則業務邏輯將永遠卡在讀取循環中。這是從文件 IO 轉向網絡編程時最核心的認知重構。