Java java.nio.file.Files move() 方法详解
java.nio.file.Files.move()
方法是 Java NIO (New I/O) 包中用于移动或重命名文件和目录的核心方法。它提供了比传统 java.io.File
类更强大和灵活的文件操作能力。
方法语法
public static Path move(Path source, Path target, CopyOption... options) throws IOException
参数说明
参数名 | 类型 | 描述 |
---|---|---|
source | Path | 要移动的源文件或目录路径 |
target | Path | 目标位置路径 |
options | CopyOption... | 可选的移动选项(可变参数) |
常用 CopyOption 选项
StandardCopyOption.REPLACE_EXISTING
:如果目标文件已存在,则替换它StandardCopyOption.ATOMIC_MOVE
:确保移动操作是原子性的LinkOption.NOFOLLOW_LINKS
:不跟随符号链接
方法功能详解
基本文件移动
最简单的移动操作,将文件从一个位置移动到另一个位置:
实例
Path source = Paths.get("C:/temp/source.txt");
Path target = Paths.get("C:/temp2/target.txt");
Files.move(source, target);
Path target = Paths.get("C:/temp2/target.txt");
Files.move(source, target);
文件重命名
移动方法也可以用于重命名文件:
实例
Path source = Paths.get("C:/temp/oldname.txt");
Path target = Paths.get("C:/temp/newname.txt");
Files.move(source, target);
Path target = Paths.get("C:/temp/newname.txt");
Files.move(source, target);
目录移动
移动整个目录(包括其内容):
实例
Path sourceDir = Paths.get("C:/temp/mydir");
Path targetDir = Paths.get("C:/temp2/mydir");
Files.move(sourceDir, targetDir);
Path targetDir = Paths.get("C:/temp2/mydir");
Files.move(sourceDir, targetDir);
高级用法
覆盖已存在文件
使用 REPLACE_EXISTING
选项覆盖已存在的目标文件:
实例
Path source = Paths.get("C:/temp/source.txt");
Path target = Paths.get("C:/temp2/target.txt");
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
Path target = Paths.get("C:/temp2/target.txt");
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
原子性移动
确保移动操作是原子性的(要么完全成功,要么完全失败):
实例
Path source = Paths.get("C:/temp/source.txt");
Path target = Paths.get("C:/temp2/target.txt");
Files.move(source, target, StandardCopyOption.ATOMIC_MOVE);
Path target = Paths.get("C:/temp2/target.txt");
Files.move(source, target, StandardCopyOption.ATOMIC_MOVE);
异常处理
move()
方法可能抛出以下异常:
IOException
:发生 I/O 错误时抛出FileAlreadyExistsException
:目标文件已存在且未指定REPLACE_EXISTING
选项DirectoryNotEmptyException
:尝试移动非空目录到不同文件系统
建议的异常处理方式:
实例
try {
Path source = Paths.get("C:/temp/source.txt");
Path target = Paths.get("C:/temp2/target.txt");
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
System.err.println("移动文件时出错: " + e.getMessage());
e.printStackTrace();
}
Path source = Paths.get("C:/temp/source.txt");
Path target = Paths.get("C:/temp2/target.txt");
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
System.err.println("移动文件时出错: " + e.getMessage());
e.printStackTrace();
}
注意事项
- 跨文件系统移动:在不同文件系统间移动文件时,实际上是复制+删除操作
- 符号链接:默认会跟随符号链接,除非指定
LinkOption.NOFOLLOW_LINKS
- 目录移动限制:不能将目录移动到其自身或其子目录中
- 文件属性:移动操作通常会保留文件的基本属性
- 性能考虑:在同一文件系统内移动通常比跨文件系统移动快得多
实际应用示例
安全移动文件
实例
public static boolean safeMoveFile(Path source, Path target) {
try {
// 尝试原子移动
Files.move(source, target, StandardCopyOption.ATOMIC_MOVE);
return true;
} catch (AtomicMoveNotSupportedException e) {
try {
// 原子移动不支持时,使用普通移动+覆盖
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
return true;
} catch (IOException ex) {
System.err.println("移动文件失败: " + ex.getMessage());
return false;
}
} catch (IOException e) {
System.err.println("移动文件失败: " + e.getMessage());
return false;
}
}
try {
// 尝试原子移动
Files.move(source, target, StandardCopyOption.ATOMIC_MOVE);
return true;
} catch (AtomicMoveNotSupportedException e) {
try {
// 原子移动不支持时,使用普通移动+覆盖
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
return true;
} catch (IOException ex) {
System.err.println("移动文件失败: " + ex.getMessage());
return false;
}
} catch (IOException e) {
System.err.println("移动文件失败: " + e.getMessage());
return false;
}
}
批量移动文件
实例
public static void batchMoveFiles(Path sourceDir, Path targetDir, String filePattern)
throws IOException {
try (DirectoryStream<Path> stream = Files.newDirectoryStream(sourceDir, filePattern)) {
for (Path sourceFile : stream) {
Path targetFile = targetDir.resolve(sourceFile.getFileName());
Files.move(sourceFile, targetFile);
}
}
}
throws IOException {
try (DirectoryStream<Path> stream = Files.newDirectoryStream(sourceDir, filePattern)) {
for (Path sourceFile : stream) {
Path targetFile = targetDir.resolve(sourceFile.getFileName());
Files.move(sourceFile, targetFile);
}
}
}
点我分享笔记