Java 目录操作
介绍
在Java编程中,目录(文件夹)操作是文件I/O操作的重要部分。Java NIO (New I/O) 包提供了比传统java.io
更强大和灵活的API来处理目录。本文将介绍如何使用Java NIO中的Path
和Files
类进行目录操作,这些类位于java.nio.file
包下。
目录操作包括:
- 创建目 录
- 列出目录内容
- 检查文件或目录是否存在
- 复制和移动目录
- 删除目录
Path接口和Files类
在Java NIO中,Path
接口和Files
类是目录操作的核心。
Path接口
Path
接口代表文件系统中的路径。路径可以指向文件或目录,可以是绝对路径或相对路径。
import java.nio.file.Path;
import java.nio.file.Paths;
// 创建Path实例
Path path1 = Paths.get("C:\\Users\\Documents\\test"); // 绝对路径
Path path2 = Paths.get("test", "subfolder"); // 相对路径
Files类
Files
类提供了各种静态方法来操作文件和目录。
创建目录
使用Files.createDirectory()
方法可以创建单个目录,而使用Files.createDirectories()
方法可以创建多级目录(如果父目录不存在,会自动创建)。
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.IOException;
public class DirectoryCreationExample {
public static void main(String[] args) {
// 创建单个目录
Path singleDir = Paths.get("test_directory");
try {
Files.createDirectory(singleDir);
System.out.println("目录创建成功: " + singleDir);
} catch (IOException e) {
System.err.println("创建目录失败: " + e.getMessage());
}
// 创建多级目录
Path multipleDir = Paths.get("parent/child/grandchild");
try {
Files.createDirectories(multipleDir);
System.out.println("多级目录创建成功: " + multipleDir);
} catch (IOException e) {
System.err.println("创建多级目录失败: " + e.getMessage());
}
}
}
输出:
目录创建成功: test_directory
多级目录创建成功: parent/child/grandchild
备注
如果目录已经存在,createDirectory()
会抛出FileAlreadyExistsException
,而createDirectories()
会正常执行不抛出异常。
检查文件或目录是否存在
使用Files.exists()
和Files.notExists()
方法可以检查路径是否指向存在的文件或目录。
Path path = Paths.get("test_directory");
boolean exists = Files.exists(path);
System.out.println("目录存在: " + exists);
// 检查是否是目录
if (exists && Files.isDirectory(path)) {
System.out.println("该路径是一个目录");
}
列出目录内容
使用Files.list()
方法可以获取目录中的直接内容(文件和子目录),而使用Files.walk()
方法可以递归地获取目录中的所有内容。
列出直接内容
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.IOException;
import java.util.stream.Stream;
public class ListDirectoryContentsExample {
public static void main(String[] args) {
Path dir = Paths.get("parent");
try (Stream<Path> entries = Files.list(dir)) {
System.out.println("目录内容:");
entries.forEach(path -> System.out.println(path.getFileName()));
} catch (IOException e) {
System.err.println("无法列出目录内容: " + e.getMessage());
}
}
}
输出可能如下:
目录内容:
child
file1.txt
file2.log
递归列出所有内容
Path dir = Paths.get("parent");
try (Stream<Path> entries = Files.walk(dir)) {
System.out.println("递归列出所有内容:");
entries.forEach(System.out::println);
} catch (IOException e) {
System.err.println("无法遍历目录: " + e.getMessage());
}
输出可能如下:
递归列出所有内容:
parent
parent\child
parent\child\grandchild
parent\child\grandchild\file3.txt
parent\file1.txt
parent\file2.log
过滤目录内容
结合Java 8的Stream API,我们可以轻松过滤目录内容。
Path dir = Paths.get("parent");
// 只列出.txt文件
try (Stream<Path> entries = Files.walk(dir)) {
System.out.println("所有.txt文件:");
entries
.filter(path -> path.toString().endsWith(".txt"))
.forEach(System.out::println);
} catch (IOException e) {
System.err.println("无法遍历目录: " + e.getMessage());
}
// 只列出目录
try (Stream<Path> entries = Files.list(dir)) {
System.out.println("直接子目录:");
entries
.filter(Files::isDirectory)
.forEach(System.out::println);
} catch (IOException e) {
System.err.println("无法列出目录: " + e.getMessage());
}
复制和移动目录
使用Files.copy()
和Files.move()
方法可以复制和移动目录。
复制目录
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.io.IOException;
public class CopyDirectoryExample {
public static void main(String[] args) {
Path source = Paths.get("source_dir");
Path target = Paths.get("target_dir");
try {
// 创建源目录和一些文件(为了演示)
Files.createDirectories(source);
Files.writeString(source.resolve("test.txt"), "Hello World");
// 只复制目录本身,不复制内容
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
System.out.println("目录已复制");
// 注意:此方法不会递归复制目录内容
// 如果需要递归复制,需要自己编写方法或使用第三方库
} catch (IOException e) {
System.err.println("复制目录失败: " + e.getMessage());
}
}
}
提示
标准的Files.copy()
方法不会递归复制目录内容,只会复制目录本身。如果需要递归复制整个目录树,可以编写自定义方法或使用第三方库,如Apache Commons IO。
移动目录
Path source = Paths.get("source_dir");
Path target = Paths.get("new_location");
try {
// 移动目录(包括其内容)
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
System.out.println("目录已移动到: " + target);
} catch (IOException e) {
System.err.println("移动目录失败: " + e.getMessage());
}