OutputStream:輸出流核心
- 所有輸出流父類,多態支援文件、網絡、內存等多種媒介
- 核心方法:
write(int b) —— 僅接收 0-255 低 8 位,高位丟棄
DataOutputStream.writeByte(int v):確保單字節寫入並追加到緩衝區
緩衝區與 flush() 關鍵作用
為什麼需要 flush?
場景:客戶端發送 300 字節請求,默認緩衝區 1024 字節 → **緩衝區未滿不發送** → 服務端陷入等待 → 客戶端以為已發送等待響應 → **雙向死鎖**
flush():強制刷新緩衝區,立即輸出數據
- **最佳實踐**:關鍵交互點**必須調用 flush**,無論你認為是否必要
System.out 默認即為緩衝流
- flush 成本極低,防患於未然
InputStream:輸入流核心
- 核心方法:
read() —— 讀取單字節,返回 0-255 或 -1(流結束)
- **阻塞特性**:無數據時阻塞調用線程,直到有字節可用或流結束
網絡通信中 -1 陷阱
- 本地文件讀取以 -1 判斷結束
- **網絡流不可用 -1 判斷業務結束**——對方未必關閉連接
- 必須設計**應用層協議**標識消息邊界:定長、分隔符、長度前綴、自描述格式(JSON/Protobuf)等
多態威力
Socket.getOutputStream() 返回 OutputStream,實際為網絡輸出流實現。掌握超類用法即掌握所有子類用法。
總結
- 理解流的雙向性:輸出流寫入媒介,輸入流讀取媒介
- 緩衝區是性能優化利器,但引入可見性延遲,**flush 是打破死鎖的關鍵**
- 網絡編程**必須設計應用協議**,不能依賴流結束標記
- 善用多態,面向
InputStream/OutputStream 編程而非具體實現