模擬一個輕量級用戶認證系統,僅使用 Java IO 流與文件持久化,實現:
| 類 | 職責 | 關鍵方法 |
|---|---|---|
User | 數據載體 | name, password, time + toString() 格式化 |
AdminUser | 業務控制器 | userRegister, userLogin, readUser, splitFile, writeUser |
Test | 交互入口 | main 循環菜單,Scanner 接收輸入 |
FileOutputStream(file, true)ps = new PrintStream(new FileOutputStream(file, true), true); // true = autoFlush System.setOut(ps); // 重定向標準輸出到文件 System.out.println(user); // 直接打印 User.toString() System.setOut(out); // 恢復控制台輸出
注意: 必須保存原始 System.out 引用,寫入後及時恢復,否則後續控制台輸出會「消失」。
splitFile()public void splitFile(String file, Setset) { try (BufferedReader br = new BufferedReader(new FileReader(file))) { String line; while ((line = br.readLine()) != null) { String[] parts = line.split(","); // 格式:User [name=xxx, password=yyy, time=zzz] String name = parts[0].substring(parts[0].indexOf('=')+1, parts[0].lastIndexOf(',')); String pwd = parts[1].substring(parts[1].indexOf('=')+1, parts[1].lastIndexOf(',')); String time = parts[2].substring(parts[2].indexOf('=')+1, parts[2].length()-1); set.add(new User(name, pwd, time)); } } catch (IOException e) { e.printStackTrace(); } }
使用 try-with-resources 自動關流,解析邏輯針對 User.toString() 格式定制。
SimpleDateFormat + Localepublic String loginTime() {
return new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss", Locale.CHINA)
.format(new Date());
}
當前實現為單線程控制台程序,HashSet 非線程安全。若擴展為多線程服務端,需:
ConcurrentHashMap.newKeySet() 替換 HashSetReentrantLock 保護關鍵區-----歡迎使用xxx系統----- 1.註冊用戶 2.登錄用戶 3.管理員登錄 4.退出 請輸入序號:1 -----用戶註冊:----- 請輸入用戶名:alice 請輸入密碼:123456 請確認密碼:123456 註冊成功! 請輸入序號:2 -----用戶登錄:----- 請輸入用戶名:alice 請輸入密碼:123456 親愛的alice,您的登錄記錄為: User [name=alice, password=123456, time=2024年01月15日 14:30:22] 您現於2024年01月15日 14:35:10登錄!
UserNotFoundException、PasswordMismatchException 替代通用 Exception。try-with-resources,消除 finally 塊樣板代碼。config.properties,支持多環境部署。AdminUser 各方法編寫 JUnit 測試,覆蓋註冊、登錄、日誌查詢主流程。本案例展示了 Java IO 流(FileInputStream/OutputStream、BufferedReader、PrintStream)構建完整業務系統的全過程。雖生產環境多用數據庫,但理解文件級持久化原理,對排查 IO 瓶頸、設計緩存策略、實現嵌入式存儲均有裨益。