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

Java 計數器教學(三):檔案版——持久化解決重啟歸零

     編輯:Java 相關知識

承接上篇環境建置,本篇將計數器資料從 application 域遷移至本地檔案,解決 Tomcat 重啟計數歸零問題,並修正檔案路徑、同步鎖、字元編碼等實戰細節。

初版:檔案讀寫基本邏輯

<%@ page import="java.io.*" %>
<%! private static final Object lock = new Object();
     private static final File file = new File("counter.dat"); %>
<% 
    Integer count = 0;
    synchronized (lock) {
        if (!file.exists()) { file.createNewFile(); count = 0; }
        else {
            FileReader reader = new FileReader(file);
            count = reader.read(); // 僅讀取第一個字元!
            reader.close();
        }
        count++;
        FileWriter writer = new FileWriter(file);
        writer.write(count); // 僅寫入低位元組!
        writer.close();
    }
%>
當前訪問次數:<%= count %>

初版缺陷分析

  1. FileReader.read() 僅讀取單一字元(0-65535),計數超過 65535 即錯誤。
  2. FileWriter.write(int) 僅寫入低 16 位,同理錯誤。
  3. 檔案路徑 counter.dat 相對路徑指向 tomcat/bin/,專案遷移不便。
  4. 未指定字元編碼,跨平台風險。

修正版:完整整數讀寫 + 專案相對路徑

<%@ page import="java.io.*" %>
<%! 
    private static final Object lock = new Object();
    private static File file = null; // 延遲初始化
%>
<% 
    Integer count = 0;
    synchronized (lock) {
        // 延遲取得專案絕對路徑:WebContent/WEB-INF/classes/counter.dat
        if (file == null) {
            file = new File(application.getRealPath(".") + "/WEB-INF/classes/counter.dat");
        }
        if (!file.exists()) { file.createNewFile(); count = 0; }
        else {
            try (BufferedReader br = new BufferedReader(new FileReader(file))) {
                String line = br.readLine();
                count = (line != null && !line.isEmpty()) ? Integer.parseInt(line.trim()) : 0;
            }
        }
        count++;
        try (PrintWriter pw = new PrintWriter(new FileWriter(file))) {
            pw.println(count); // 完整整數文本寫入,支援任意大小
        }
    }
%>
當前訪問次數:<%= count %>

修正要點

  • BufferedReader + PrintWriter:按行讀寫文本,支援任意大小整數,跨平台無編碼問題。
  • try-with-resources:JDK 7+ 自動關閉流,無洩漏。
  • application.getRealPath("."):動態取得專案部署根路徑,檔案固定在 WEB-INF/classes 受容器保護區,外部無法直接下載。
  • 延遲初始化 File:application 在 JSP 首次編譯時才可用,故在首次請求時初始化路徑。
  • 同步鎖保持:多線程併發寫入仍需 synchronized(lock) 保護。

生成檔案示例

counter.dat 檔案內容

12345

遺留問題

  • 單機檔案鎖:集群環境多節點無法共享檔案,需外部分散式鎖或資料庫。
  • I/O 效能:高併發下頻繁磁碟讀寫成瓶頸。

下一篇將實作JDBC 版,使用 MySQL 持久化,支援集群與高併發。

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