Java 檔案操作核心在於 java.io 套件提供的位元組流(InputStream/OutputStream)與字元流(Reader/Writer)體系。本文系統整理常用類別、方法與最佳實務,並提供一個功能完整的檔案工具類原始碼。
| 類別 | 類型 | 用途 | 常見子類別 |
|---|---|---|---|
InputStream | 抽象類別 | 位元組輸入(二進位資料) | FileInputStream, ByteArrayInputStream, BufferedInputStream |
OutputStream | 抽象類別 | 位元組輸出 | FileOutputStream, ByteArrayOutputStream, BufferedOutputStream |
Reader | 抽象類別 | 字元輸入(文字資料,Unicode) | FileReader, BufferedReader, InputStreamReader |
Writer | 抽象類別 | 字元輸出 | FileWriter, BufferedWriter, OutputStreamWriter, PrintWriter |
File | 實體類別 | 檔案/目錄路徑操作(不處理內容) | — |
RandomAccessFile | 實體類別 | 隨機存取(可讀寫、可定位指標) | — |
InputStream.read():讀取單一位元組,回傳 int (0-255),結束回傳 -1。InputStream.read(byte[] b):讀入位元組陣列,回傳實際讀取數。Reader.read(char[] cbuf):讀入字元陣列。BufferedReader.readLine():按行讀取文字,不含換行符,結束回傳 null。PrintWriter.println():輸出字串並自動換行、刷新緩衝區。File.listFiles():列出目錄下所有檔案與子目錄(回傳 File[])。File.mkdir() / mkdirs():建立單層/多層目錄。File.createNewFile():建立新檔案(原子操作)。File.delete():刪除檔案或空目錄。package mytestfiles;
import java.io.*;
import java.util.Arrays;
public class FilesUtil {
/** 寫入字串陣列,每行一筆 */
public void writeLines(String dir, String fileName, String[] lines) throws IOException {
File f = new File(dir, fileName);
try (FileWriter fw = new FileWriter(f);
PrintWriter pw = new PrintWriter(fw)) {
for (String line : lines) {
pw.println(line);
}
}
}
/** 寫入單一字串 */
public void writeString(String dir, String fileName, String content) throws IOException {
File f = new File(dir, fileName);
try (FileWriter fw = new FileWriter(f)) {
fw.write(content);
}
}
/** 建立或刪除檔案 */
public boolean createOrDeleteFile(String dir, String fileName) throws IOException {
File f = new File(dir, fileName);
if (f.exists()) {
return f.delete();
} else {
return f.createNewFile();
}
}
/** 建立或刪除目錄 */
public boolean createOrDeleteDir(String dir, String dirName) {
File f = new File(dir, dirName);
try {
if (f.exists()) {
return deleteDirectory(f); // 遞迴刪除非空目錄
} else {
return f.mkdirs();
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private boolean deleteDirectory(File dir) {
File[] files = dir.listFiles();
if (files != null) {
for (File f : files) {
if (f.isDirectory()) deleteDirectory(f);
else f.delete();
}
}
return dir.delete();
}
/** 列出目錄內容 */
public void listDirectory(String dirPath) {
File dir = new File(dirPath);
File[] files = dir.listFiles();
if (files == null) return;
for (File f : files) {
System.out.println((f.isDirectory() ? "[DIR] " : "[FILE] ") + f.getName());
}
}
/** 檢查檔案是否為空 */
public boolean isFileEmpty(String dir, String fileName) throws IOException {
File f = new File(dir, fileName);
try (FileReader fr = new FileReader(f)) {
return fr.read() == -1;
}
}
/** 讀取整個檔案內容(小檔案適用) */
public String readAll(String dir, String fileName) throws IOException {
File f = new File(dir, fileName);
StringBuilder sb = new StringBuilder();
try (FileReader fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr)) {
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append(System.lineSeparator());
}
}
return sb.toString();
}
/** 逐行讀取並處理(大檔案適用) */
public void processLines(String dir, String fileName, LineProcessor processor) throws IOException {
File f = new File(dir, fileName);
try (FileReader fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr)) {
String line;
while ((line = br.readLine()) != null) {
processor.process(line);
}
}
}
@FunctionalInterface
public interface LineProcessor {
void process(String line);
}
// 測試主程式
public static void main(String[] args) throws IOException {
FilesUtil util = new FilesUtil();
String base = "f:/test_io/";
util.createOrDeleteDir(base, "demo");
String[] data = new String[50];
Arrays.setAll(data, i -> "資料行 " + i);
util.writeLines(base + "demo/", "data.txt", data);
System.out.println("=== 逐行處理 ===");
util.processLines(base + "demo/", "data.txt", line -> System.out.println(line));
}
}
FileReader/Writer 或 BufferedReader/Writer,自動處理編碼。readAllBytes() 或一次讀入記憶體,使用 BufferedReader.readLine() 或 InputStream.read(byte[]) 迴圈。close() 被呼叫。StandardCharsets.UTF_8 搭配 InputStreamReader/OutputStreamWriter,避免平台預設編碼差異。java.nio.file.Path、Files、Paths API,功能更強大(複製、移動、屬性讀取、走訪目錄樹)。import java.nio.file.*;
import java.io.IOException;
import java.util.stream.Stream;
public class ModernFileOps {
public static void main(String[] args) throws IOException {
Path dir = Paths.get("f:/test_io/demo");
Files.createDirectories(dir);
// 寫入
Files.write(dir.resolve("data.txt"),
Arrays.asList("Line 1", "Line 2"),
StandardCharsets.UTF_8, StandardOpenOption.CREATE);
// 逐行串流讀取 (自動關閉)
try (Stream lines = Files.lines(dir.resolve("data.txt"))) {
lines.forEach(System.out::println);
}
// 走訪目錄樹
Files.walkFileTree(dir, new SimpleFileVisitor() {
@Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
System.out.println(file);
return FileVisitResult.CONTINUE;
}
});
}
}