Java 檔案處理

Java 提供多種方式處理檔案的讀取和寫入。

File 類別

import java.io.File;

File file = new File("test.txt");

// 檔案資訊
System.out.println(file.exists());       // 是否存在
System.out.println(file.getName());      // 檔案名稱
System.out.println(file.getPath());      // 路徑
System.out.println(file.getAbsolutePath()); // 絕對路徑
System.out.println(file.length());       // 檔案大小(bytes)
System.out.println(file.isFile());       // 是否為檔案
System.out.println(file.isDirectory());  // 是否為目錄
System.out.println(file.canRead());      // 是否可讀
System.out.println(file.canWrite());     // 是否可寫

// 建立/刪除
file.createNewFile();  // 建立檔案
file.mkdir();          // 建立目錄
file.delete();         // 刪除

// 列出目錄內容
File dir = new File(".");
String[] files = dir.list();
File[] fileList = dir.listFiles();

更多說明請參考 Java 檔案操作

讀取檔案

FileReader + BufferedReader

try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}

Files.readAllLines() (Java 7+)

import java.nio.file.Files;
import java.nio.file.Paths;

// 讀取所有行
List<String> lines = Files.readAllLines(Paths.get("file.txt"));

// 讀取整個檔案為字串 (Java 11+)
String content = Files.readString(Paths.get("file.txt"));

Scanner

try (Scanner scanner = new Scanner(new File("file.txt"))) {
    while (scanner.hasNextLine()) {
        String line = scanner.nextLine();
        System.out.println(line);
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

更多說明請參考 Java 讀取檔案

寫入檔案

FileWriter + BufferedWriter

try (BufferedWriter writer = new BufferedWriter(new FileWriter("file.txt"))) {
    writer.write("Hello World");
    writer.newLine();
    writer.write("Second line");
} catch (IOException e) {
    e.printStackTrace();
}

// 追加模式
try (BufferedWriter writer = new BufferedWriter(new FileWriter("file.txt", true))) {
    writer.write("Appended text");
} catch (IOException e) {
    e.printStackTrace();
}

PrintWriter

try (PrintWriter writer = new PrintWriter("file.txt")) {
    writer.println("Hello World");
    writer.printf("Number: %d%n", 42);
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

Files.write() (Java 7+)

import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

// 寫入
Files.write(Paths.get("file.txt"), "Hello World".getBytes());

// 寫入多行
List<String> lines = Arrays.asList("Line 1", "Line 2", "Line 3");
Files.write(Paths.get("file.txt"), lines);

// 追加
Files.write(Paths.get("file.txt"), "Appended".getBytes(), StandardOpenOption.APPEND);

// Java 11+
Files.writeString(Paths.get("file.txt"), "Hello World");

更多說明請參考 Java 寫入檔案

try-with-resources

自動關閉資源:

// 自動關閉 reader
try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"));
     BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
    
    String line;
    while ((line = reader.readLine()) != null) {
        writer.write(line.toUpperCase());
        writer.newLine();
    }
} catch (IOException e) {
    e.printStackTrace();
}

NIO.2 (Java 7+)

Path 和 Paths

import java.nio.file.Path;
import java.nio.file.Paths;

Path path = Paths.get("dir/file.txt");
Path path2 = Path.of("dir", "file.txt");  // Java 11+

System.out.println(path.getFileName());   // file.txt
System.out.println(path.getParent());     // dir
System.out.println(path.toAbsolutePath());

Files 工具類別

import java.nio.file.Files;

Path source = Paths.get("source.txt");
Path target = Paths.get("target.txt");

// 複製
Files.copy(source, target);

// 移動
Files.move(source, target);

// 刪除
Files.delete(target);
Files.deleteIfExists(target);

// 建立目錄
Files.createDirectory(Paths.get("newdir"));
Files.createDirectories(Paths.get("a/b/c"));  // 建立多層

// 檢查
Files.exists(path);
Files.isDirectory(path);
Files.isReadable(path);
Files.size(path);

更多說明請參考 Java NIO

完整範例

複製檔案

public static void copyFile(String source, String target) throws IOException {
    try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(source));
         BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(target))) {
        
        byte[] buffer = new byte[8192];
        int bytesRead;
        while ((bytesRead = in.read(buffer)) != -1) {
            out.write(buffer, 0, bytesRead);
        }
    }
}

// 或使用 NIO
Files.copy(Paths.get("source.txt"), Paths.get("target.txt"));

讀取設定檔

public static Properties loadConfig(String filename) throws IOException {
    Properties props = new Properties();
    try (InputStream input = new FileInputStream(filename)) {
        props.load(input);
    }
    return props;
}

Properties config = loadConfig("config.properties");
String value = config.getProperty("key");

遍歷目錄

// 遍歷目錄
Files.walk(Paths.get("dir"))
    .filter(Files::isRegularFile)
    .forEach(System.out::println);

// 只找 .java 檔案
Files.walk(Paths.get("src"))
    .filter(p -> p.toString().endsWith(".java"))
    .forEach(System.out::println);