Java java.nio.file.Files move() 方法详解

Java File Java java.nio.file.Files


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 source = Paths.get("C:/temp/oldname.txt");
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);

高级用法

覆盖已存在文件

使用 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 source = Paths.get("C:/temp/source.txt");
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();
}

注意事项

  1. 跨文件系统移动:在不同文件系统间移动文件时,实际上是复制+删除操作
  2. 符号链接:默认会跟随符号链接,除非指定 LinkOption.NOFOLLOW_LINKS
  3. 目录移动限制:不能将目录移动到其自身或其子目录中
  4. 文件属性:移动操作通常会保留文件的基本属性
  5. 性能考虑:在同一文件系统内移动通常比跨文件系统移动快得多

实际应用示例

安全移动文件

实例

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;
    }
}

批量移动文件

实例

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);
        }
    }
}

Java File Java java.nio.file.Files