Java I/O 是基礎且高頻的開發場景。本文通過三個完整代碼示例,系統講解 FilenameFilter 文件過濾、FileInputStream 位元組流讀取、FileOutputStream 位元組流寫入的核心用法與常見坑點。
public class FileFilterDemo implements FilenameFilter {
public static void main(String[] args) {
File dir = new File("F:\\java\\workspace\\Fanshe");
String[] matched = dir.list(new FileFilterDemo()); // 回調 accept()
if (matched != null && matched.length > 0) {
System.out.println("匹配到: " + matched[0]);
}
}
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".classpath"); // 只保留 .classpath 結尾
}
}
關鍵點:
list(FilenameFilter) 會對目錄下每個文件名調用 accept(),返回 true 者納入結果陣列name.startsWith()、name.matches(regex) 等list() 若目錄不存在或非目錄返回 null,需非空判斷public class FileReadDemo {
public static void main(String[] args) throws IOException {
File file = new File("F:\\java\\workspace\\Fanshe\\src\\com\\cyg\\fanshe.java");
try (FileInputStream fis = new FileInputStream(file)) {
byte[] buffer = new byte[fis.available()]; // 獲取文件位元組數(小文件適用)
int readCount = fis.read(buffer); // 一次性讀入
if (readCount != -1) {
System.out.println(new String(buffer, StandardCharsets.UTF_8)); // 指定編碼
}
} // try-with-resources 自動關閉
}
}
進階建議:
byte[4096] 緩衝區循環讀取,避免 OOMFileReader / BufferedReader 逐行讀取StandardCharsets.UTF_8 避免平台預設編碼差異導致亂碼public class FileWriteDemo {
public static void main(String[] args) throws IOException {
File file = new File("F:\\a.txt");
try (FileOutputStream fos = new FileOutputStream(file)) { // 預設覆蓋模式
String content = "admin";
fos.write(content.getBytes(StandardCharsets.UTF_8));
fos.flush(); // 強制刷新緩衝區
} // 自動 close() 含 flush
}
}
常用變體:
new FileOutputStream(file, true)BufferedOutputStreamFileWriter / BufferedWriter / PrintWriter| 場景 | 推薦類/方法 | 關鍵參數 |
|---|---|---|
| 小文件全讀 | Files.readAllBytes() / FileInputStream.available() | 指定 Charset |
| 大文件流式讀 | BufferedInputStream + byte[8192] | 循環 read() 直到 -1 |
| 文本逐行讀 | Files.lines() / BufferedReader.readLine() | try-with-resources |
| 覆蓋寫入 | FileOutputStream / Files.write() | StandardOpenOption.CREATE |
| 追加寫入 | FileOutputStream(file,true) / Files.write(..., APPEND) | StandardOpenOption.APPEND |
close() → 檔案鎖佔用、資料未刷新 → 統一使用 try-with-resourcesavailable() 用於大文件 → 記憶體溢出 → 改用固定緩衝區循環讀取