首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Java FileInputStream.read() 返回值深度解析:為什麼輸出的是字節數值而非讀取計數?

     編輯:程式設計疑難解答

代碼現場

FileInputStream in = new FileInputStream("F:/Test.txt");
FileOutputStream out = new FileOutputStream("G:/Test.txt");
int b;

while ((b = in.read()) != -1) {
    out.write(b);
    System.out.println(b);
}
in.close();
out.close();

輸出結果:

206
210
202
199
186
195
200
203

核心誤區

提問者認為 read() 返回「讀取到的字節個數」,應為 1。實際上,InputStream.read() 返回的是下一個字節的數值(0-255),而非計數。-1 表示流結束。

官方 API 定義

read():從輸入流中讀取下一個數據字節。該字節作為 0 到 255 範圍內的 int 返回。若已到達流末尾,則返回 -1。

逐行執行邏輯

  1. in.read() 從文件讀取 1 個字節(8 位),返回其無符號值(0-255)作為 int。
  2. 賦值給 b,判斷 b != -1 決定是否繼續循環。
  3. out.write(b) 將 b 的低 8 位作為字節寫入輸出流。
  4. System.out.println(b) 打印該字節的十進制整數值。

輸出數值含義

輸出的 206, 210, 202... 是文件中連續字節的十進制表示。若文件為文本,這些數值對應字符編碼(如 UTF-8、GBK)下的字節序列。例如:

  • 若文件為 ASCII 文本 "Test",輸出應為 84 101 115 116。
  • 示例輸出數值較大(>127),暗示文件可能包含中文字符的 UTF-8 多字節編碼,或非文本二進制數據。

write(b) 運作機制

public void write(int b) throws IOException {
    // 僅寫入 b 的低 8 位(b & 0xFF)
    // 相當於寫入單字節:byte[] buf = {(byte)b}; write(buf);
}

write(int) 將參數作為單字節寫入,高 24 位被忽略。這正是流複製的核心:逐字節讀取、逐字節寫入。

字節 vs 字符關鍵區別

概念InputStream/OutputStreamReader/Writer
處理單位字節字符
編碼轉換無,原始二進制自動按編碼轉換
read() 返回字節值 (0-255) 或 -1字符碼點 或 -1
適用場景圖片、視頻、二進制文件、文本複製文本處理、字符級操作

最佳實踐建議

  • 文本文件複製優先使用 Files.copy() (NIO.2) 或緩衝流 BufferedInputStream/OutputStream 提升性能。
  • 需按字符處理時,使用 InputStreamReader / OutputStreamWriter 指定編碼。
  • 調試二進制文件時,配合十六進制查看器(如 xxd、HxD)對照字節值分析。

總結

FileInputStream.read() 返回的是字節的數值,而非讀取計數。理解「流操作字節、字節值範圍 0-255、-1 表示結束」是正確使用 Java IO 流的基石。示例代碼完美演示了逐字節複製文件的標準模式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved