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

Java 通訊錄 TXT 文件分頁顯示實作指南

     編輯:程式設計疑難解答

問題背景

在開發 Java 通訊錄應用時,常遇到資料量過大導致介面載入緩慢的問題。使用者希望將儲存在 TXT 文件中的聯繫人記錄,以每頁 20 筆的方式分頁顯示,並提供上一頁、下一頁導航功能。

核心解決思路

分頁邏輯本質上與資料庫分頁查詢一致:根據當前頁碼計算資料的起始與結束索引,僅讀取該範圍內的記錄。對於 TXT 文件,可採用「全量讀取後切片」或「流式讀取定位」兩種策略。

方案一:全量讀取後記憶體切片(適合中小型資料)

// 讀取所有行到 List
List<String> allLines = Files.readAllLines(Paths.get("D:/AddressBook.txt"), StandardCharsets.UTF_8);
int pageSize = 20;
int totalPages = (int) Math.ceil((double) allLines.size() / pageSize);

// 獲取指定頁面資料 (page 從 1 開始)
public List<String> getPageData(int page) {
    int start = (page - 1) * pageSize;
    int end = Math.min(start + pageSize, allLines.size());
    return allLines.subList(start, end);
}

方案二:RandomAccessFile 定位讀取(適合大文件)

public List<String> readPage(String filePath, int page, int pageSize) throws IOException {
    List<String> result = new ArrayList<>();
    try (RandomAccessFile raf = new RandomAccessFile(filePath, "r")) {
        long fileLength = raf.length();
        long avgLineLength = estimateAvgLineLength(raf); // 預估平均行長
        long startPos = (page - 1) * pageSize * avgLineLength;
        raf.seek(Math.max(0, startPos));
        
        // 略過不完整行
        if (startPos > 0) raf.readLine();
        
        String line;
        while ((line = raf.readLine()) != null && result.size() < pageSize) {
            result.add(line);
        }
    }
    return result;
}

介面整合建議

  • 在顯示區域上方/下方新增「首頁」「上一頁」「下一頁」「尾頁」按鈕
  • 使用 JTextArea 搭配 JScrollPane 展示分頁內容
  • 維護當前頁碼狀態,按鈕點擊時重新呼叫讀取方法並刷新顯示

進階優化

若需支援排序、篩選(如按性別查詢)後的分頁,建議先將符合條件的記錄索引收集到列表,再對索引列表進行分頁切片,避免重複掃描文件。

完整程式碼結構參考

public class AddressBookPager {
    private final String filePath;
    private final int pageSize;
    private List<Integer> lineOffsets; // 儲存每行起始偏移量
    
    public AddressBookPager(String filePath, int pageSize) {
        this.filePath = filePath;
        this.pageSize = pageSize;
        buildIndex();
    }
    
    private void buildIndex() throws IOException {
        lineOffsets = new ArrayList<>();
        try (RandomAccessFile raf = new RandomAccessFile(filePath, "r")) {
            long offset = 0;
            String line;
            while ((line = raf.readLine()) != null) {
                lineOffsets.add((int) offset);
                offset = raf.getFilePointer();
            }
        }
    }
    
    public List<String> getPage(int page) throws IOException {
        List<String> pageData = new ArrayList<>();
        int startIdx = (page - 1) * pageSize;
        if (startIdx >= lineOffsets.size()) return pageData;
        
        try (RandomAccessFile raf = new RandomAccessFile(filePath, "r")) {
            for (int i = startIdx; i < lineOffsets.size() && i < startIdx + pageSize; i++) {
                raf.seek(lineOffsets.get(i));
                pageData.add(raf.readLine());
            }
        }
        return pageData;
    }
}

採用索引映射方式可實現 O(1) 定位,大幅提升大文件分頁效能。實際專案中建議搭配 SwingWorker 異步載入,避免阻塞 UI 執行緒。

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