首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java FileFilter 與 BufferedReader 讀行處理實戰代碼

     編輯:Java 相關知識

實戰場景:批量讀取目錄下所有 .txt 壓測日誌,提取關鍵指標(吞吐量、QPS、延遲、錯誤率等)並彙總。展示 FileFilter 過濾與 BufferedReader 高效讀行的最佳實踐。

完整實戰代碼

package com.cjonline.foundation.evisa;

import java.io.*;
import java.math.BigDecimal;

public class Test {
    public static void main(String[] args) throws Exception {
        // 1. FileFilter 過濾 .txt 檔案
        File[] files = new File("src").listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {
                return file.getName().endsWith(".txt");
            }
        });

        // 2. 定義待提取指標關鍵字
        String[] keys = {
            "Total transferred:", "Requests per second:", "[ms] (mean)",
            "Time per request:", "Transfer rate:", "Failed requests:", "Write errors:"
        };

        // 3. 逐檔處理
        for (File file : files) {
            System.out.println("---------【 file name : " + file.getName() + "】----------");
            try (FileInputStream is = new FileInputStream(file);
                 BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
                
                BigDecimal[] results = calPress(br);
                for (int i = 0; i < keys.length; i++) {
                    System.out.println(keys[i] + "    " + results[i]);
                }
                System.out.println();
            }
        }
    }

    // 4. 解析邏輯:按行讀取 + 前綴/後綴匹配 + 分割提取數值
    private static BigDecimal[] calPress(BufferedReader br) throws IOException {
        BigDecimal[] res = new BigDecimal[7];
        Arrays.fill(res, BigDecimal.ZERO);
        
        String line;
        while ((line = br.readLine()) != null) {
            if (line.startsWith("Total transferred:")) {
                res[0] = res[0].add(extractValue(line, -2));
            } else if (line.startsWith("Requests per second:")) {
                res[1] = res[1].add(extractValue(line, -3));
            } else if (line.endsWith("[ms] (mean)")) {
                res[2] = res[2].add(extractValue(line, -3));
            } else if (line.startsWith("Time per request:") && !line.endsWith("[ms] (mean)")) {
                res[3] = res[3].add(extractValue(line, -7));
            } else if (line.startsWith("Transfer rate:")) {
                res[4] = res[4].add(extractValue(line, -3));
            } else if (line.startsWith("Failed requests:")) {
                res[5] = res[5].add(extractValue(line, -1));
            } else if (line.startsWith("Write errors:")) {
                res[6] = res[6].add(extractValue(line, -1));
            }
        }
        return res;
    }

    // 輔助:分割行並提取指定索引位置的數值
    private static BigDecimal extractValue(String line, int indexFromEnd) {
        String[] parts = line.split("\\s+");
        String valStr = parts[parts.length + indexFromEnd]; // 負索引從後往前
        return BigDecimal.valueOf(Double.parseDouble(valStr));
    }
}

關鍵技術點解析

  1. FileFilter 匿名類/Lambda:JDK 8+ 可簡化為 f -> f.getName().endsWith(".txt")
  2. try-with-resources:自動關閉流,防止資源洩漏(JDK 7+)
  3. BufferedReader.readLine():按行讀取,記憶體友好,適合大文件
  4. BigDecimal 精確運算:避免 double 浮點誤差,金融/指標彙總必用
  5. 字串分割提取:split("\\s+") 正則匹配多空白,負索引從後取值更穩健

進階優化建議

  • 大量文件併發處理:ExecutorService + CompletableFuture
  • 超大文件:MappedByteBuffer 記憶體映射或 Lines.lines() 串流並行
  • 指標解析通用化:正則命名捕獲組 (?<value>\d+\.?\d*) + 編譯 Pattern 復用
  • 結果輸出:JSON/CSV 序列化,便於下游分析系統消費
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved