365. Java IO API - 移动文件或目录

0 阅读2分钟

365. Java IO API - 移动文件或目录

移动文件或目录是文件系统操作中的常见需求,Java 提供了非常方便的方法来实现这一操作:Files.move()


✅ 1. 基本用法

Files.move(sourcePath, targetPath);

这行代码会尝试将 sourcePath 移动到 targetPath,但如果目标路径已存在,move() 方法将抛出 FileAlreadyExistsException


⚙️ 2. 常用选项(CopyOption)

你可以传递多个选项来定制移动操作,这些选项以可变参数(varargs)的形式传入:

Files.move(sourcePath, targetPath, REPLACE_EXISTING, ATOMIC_MOVE);
枚举常量含义说明
REPLACE_EXISTING如果目标已经存在,则替换目标文件或目录。对于符号链接,会替换链接本身。
ATOMIC_MOVE确保以原子方式移动文件,意味着文件在移动过程中不会出现部分完成的状态。

📁 3. 移动目录

  • 空目录可以直接移动。
  • 非空目录的移动操作会依赖操作系统的支持。在 UNIX 系统中,如果目录在同一分区内进行移动,实际上是通过重命名来实现的,甚至包含子文件的目录也能被移动。
Path sourceDir = Paths.get("/home/user/dir");
Path targetDir = Paths.get("/home/user/dir_backup");
Files.move(sourceDir, targetDir, REPLACE_EXISTING);

🧪 示例:使用 ATOMIC_MOVE 保证原子操作

import java.nio.file.*;
import static java.nio.file.StandardCopyOption.*;

public class FileMoveDemo {
    public static void main(String[] args) {
        Path source = Paths.get("example.txt");
        Path target = Paths.get("backup/example.txt");

        try {
            Files.move(source, target, REPLACE_EXISTING, ATOMIC_MOVE);
            System.out.println("✅ 文件成功移动!");

        } catch (IOException e) {
            System.err.println("❌ 文件移动失败:" + e.getMessage());
        }
    }
}

这里的 ATOMIC_MOVE 保证了文件在移动过程中不会被其他进程看到半成品。如果操作系统或文件系统不支持原子操作,会抛出异常。


🔄 4. 使用 Varargs 传递多个选项

你可以传入多个 CopyOption 枚举值来定制操作。例如:

Files.move(source, target, REPLACE_EXISTING, ATOMIC_MOVE);

这会执行一个替换目标文件且确保原子性的移动操作。


⚠️ 5. 错误处理

如果目标路径已存在并且你没有使用 REPLACE_EXISTINGmove() 会抛出 FileAlreadyExistsException。如果操作系统不支持原子操作(尤其是 ATOMIC_MOVE),会抛出 IOException

try {
    Files.move(sourcePath, targetPath, REPLACE_EXISTING);
} catch (FileAlreadyExistsException e) {
    System.err.println("❌ 目标文件已存在,未能移动!");
} catch (IOException e) {
    System.err.println("❌ 文件移动失败:" + e.getMessage());
}

⚙️ 6. 原子操作(Atomic Operations)

原子操作意味着整个操作要么完成,要么完全失败。对于多进程环境中的文件操作,原子操作非常关键。举个例子,如果你在复制文件时发生了中断,原子操作可以保证文件要么完全复制,要么根本不进行任何复制操作,避免部分完成的状态。


📝 小结

操作类别方法
文件/目录移动Files.move(Path, Path, ...)
移动选项REPLACE_EXISTING, ATOMIC_MOVE