Java 提供了多種處理檔案的 API,從傳統的 java.io.File 到現代的 NIO.2(java.nio.file),本文整理常用的檔案操作方式。
File 類(傳統方式)
java.io.File 是 Java 最早的檔案操作類,適合基本的路徑操作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import java.io.File;
File file = new File("/path/to/file.txt");
// 取得檔案資訊
System.out.println(file.getName()); // file.txt
System.out.println(file.getAbsolutePath()); // /path/to/file.txt
System.out.println(file.length()); // 檔案大小(bytes)
System.out.println(file.exists()); // 是否存在
System.out.println(file.isDirectory()); // 是否為目錄
// 建立目錄
new File("/path/to/newdir").mkdirs();
// 刪除檔案
file.delete();
|
Path / Files(NIO.2,推薦)
Java 7 引入的 NIO.2 提供更強大且直觀的 API,是現代 Java 開發的首選:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;
Path path = Paths.get("/path/to/file.txt");
// 取得路徑資訊
System.out.println(path.getFileName()); // file.txt
System.out.println(path.getParent()); // /path/to
System.out.println(path.toAbsolutePath());
// 從字串路徑取得檔名(不含副檔名)
Path p = Paths.get("/home/user/document.pdf");
String nameWithExt = p.getFileName().toString(); // document.pdf
String name = nameWithExt.replaceFirst("[.][^.]+$", ""); // document
|
讀取文字檔
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import java.nio.file.*;
import java.io.*;
import java.util.List;
// 方式一:一次讀取所有行(小檔案適用)
List<String> lines = Files.readAllLines(Paths.get("file.txt"));
lines.forEach(System.out::println);
// 方式二:讀取整個檔案為字串(Java 11+)
String content = Files.readString(Paths.get("file.txt"));
// 方式三:BufferedReader(大檔案適用,逐行讀取)
try (BufferedReader reader = Files.newBufferedReader(Paths.get("file.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
// 方式四:Stream(搭配 lambda,記得關閉)
try (var lines2 = Files.lines(Paths.get("file.txt"))) {
lines2.filter(l -> l.contains("keyword"))
.forEach(System.out::println);
}
|
寫入檔案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.io.*;
// 方式一:寫入字串(Java 11+)
Files.writeString(Paths.get("output.txt"), "Hello, World!\n");
// 方式二:寫入多行
List<String> lines = List.of("第一行", "第二行", "第三行");
Files.write(Paths.get("output.txt"), lines, StandardCharsets.UTF_8);
// 方式三:附加內容到現有檔案
Files.write(
Paths.get("output.txt"),
"追加內容\n".getBytes(StandardCharsets.UTF_8),
StandardOpenOption.APPEND, StandardOpenOption.CREATE
);
// 方式四:BufferedWriter(適合大量寫入)
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get("output.txt"))) {
writer.write("第一行");
writer.newLine();
writer.write("第二行");
}
|
複製、移動、刪除檔案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import java.nio.file.*;
Path source = Paths.get("source.txt");
Path target = Paths.get("target.txt");
// 複製(若目標存在則覆蓋)
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
// 移動(等同重新命名或移動位置)
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
// 刪除(若不存在會拋出例外)
Files.delete(target);
// 刪除(若不存在不拋出例外)
Files.deleteIfExists(target);
|
遍歷目錄
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
import java.nio.file.*;
// 方式一:列出當前目錄的直接子項目
try (var stream = Files.list(Paths.get("/path/to/dir"))) {
stream.forEach(System.out::println);
}
// 方式二:遞迴遍歷所有檔案(Files.walk)
try (var stream = Files.walk(Paths.get("/path/to/dir"))) {
stream.filter(Files::isRegularFile) // 只要一般檔案
.filter(p -> p.toString().endsWith(".java"))
.forEach(System.out::println);
}
// 方式三:查找符合條件的檔案(Files.find)
try (var stream = Files.find(Paths.get("/path/to/dir"),
Integer.MAX_VALUE, // 最大深度
(path, attrs) -> attrs.isRegularFile() && path.toString().endsWith(".log"))) {
stream.forEach(System.out::println);
}
|
取得人類可讀的檔案大小
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import java.nio.file.*;
long bytes = Files.size(Paths.get("largefile.zip"));
// 轉換為人類可讀格式
String humanReadable;
if (bytes < 1024) {
humanReadable = bytes + " B";
} else if (bytes < 1024 * 1024) {
humanReadable = String.format("%.1f KB", bytes / 1024.0);
} else if (bytes < 1024 * 1024 * 1024) {
humanReadable = String.format("%.1f MB", bytes / (1024.0 * 1024));
} else {
humanReadable = String.format("%.1f GB", bytes / (1024.0 * 1024 * 1024));
}
System.out.println(humanReadable);
|
讀取 Resources 資料夾中的檔案
在 Spring Boot 或 Maven 專案中,讀取 src/main/resources 下的檔案:
1
2
3
4
5
6
7
8
9
10
|
// 方式一:透過 ClassLoader
InputStream is = getClass().getClassLoader().getResourceAsStream("data.json");
// 方式二:透過 Class(路徑需以 / 開頭)
InputStream is2 = getClass().getResourceAsStream("/data.json");
// 搭配 BufferedReader 讀取文字
try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
String content = reader.lines().collect(Collectors.joining("\n"));
}
|
參考資料