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

Java File.length() 與 BufferedReader 讀取長度不一致:不可見字符(換行符)導致

     編輯:程式設計綜合問答

問題現象

讀取文件累加 `line.length()` 約為 `file.length()` 的 85%,差值約 15%。

根本原因

`BufferedReader.readLine()` 會剝離行終結符(`\n`、`\r`、`\r\n`),而 `File.length()` 統計文件原始字節數(包含換行符)。

  • Windows:`\r\n` (2 字節/行)。
  • Linux/macOS:`\n` (1 字節/行)。
  • 若文件 1000 行,Windows 下差值約 2000 字節,佔比視文件大小而定(~15% 合理)。

驗證代碼

File file = new File(path);
long fileLen = file.length();

try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
    String line;
    long charCount = 0;
    long lineCount = 0;
    while ((line = reader.readLine()) != null) {
        charCount += line.length(); // 無換行符
        lineCount++;
    }
    System.out.println("文件字節數: " + fileLen);
    System.out.println("字符數(無換行): " + charCount);
    System.out.println("行數: " + lineCount);
    System.out.println("推算換行符字節: " + (fileLen - charCount));
    // Windows 預期 ≈ lineCount * 2
}

解決方案(按需選擇)

  1. 需精確字符數:用 `FileReader`/`InputStreamReader` 逐字符讀取(含換行符),或 `Files.readString(Path)` (Java 11+) 獲取完整字符串再 `.length()`。
  2. 需行數統計:直接數 `readLine()` 非 null 次數。
  3. 進度條顯示:用 `FileChannel.position()` / `RandomAccessFile.getFilePointer()` 獲取已讀**字節位置**,與 `file.length()` 同維度,進度條平滑準確。

進度條最佳實踐

try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
    byte[] buffer = new byte[8192];
    int len;
    long readBytes = 0;
    while ((len = raf.read(buffer)) != -1) {
        readBytes += len;
        int progress = (int) (readBytes * 100 / fileLen);
        updateProgress(progress);
        // 處理 buffer...
    }
}

總結

`File.length()` = 磁盤字節數(含換行符),`readLine()` 累加 = 內容字符數(不含換行符)。**單位不一致**導致差異。進度條請使用字節位置 API。

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