Java 批量复制和移动文件!

Java 文件处理的最佳实践:批量复制和移动文件

在 Java 项目中,文件处理是一个常见的需求,特别是在需要批量复制或移动文件时。本文将深入探讨如何使用 Java 处理文件,特别是利用 NIO(New Input/Output)包来简化文件操作。结尾附源文件!
在这里插入图片描述

一、文件工具类的实现

下面是一个 FileUtil 工具类,提供了一系列文件处理功能,如获取文件扩展名、判断文件是否存在、输出文件、移动和复制目录等。

1. 移动文件或目录

public static void moveDirectoryContents(String sourceDirectory, String targetDirectory, List<String> whiteList) throws IOException {
    Path sourcePath = Paths.get(sourceDirectory);
    Path targetPath = Paths.get(targetDirectory);

    // 确保源存在
    if (!Files.exists(sourcePath)) {
        throw new IOException("源路径不存在: " + sourceDirectory);
    }

    // 如果源是文件
    if (Files.isRegularFile(sourcePath)) {
        Files.move(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
        return;
    }

    // 处理目录移动逻辑
    try {
        Files.walk(sourcePath)
                .filter(path -> !path.equals(sourcePath))
                .filter(path -> whiteList.stream().noneMatch(item -> path.toString().contains(item)))
                .forEach(path -> {
                    try {
                        Path relativePath = sourcePath.relativize(path);
                        Files.move(path, targetPath.resolve(relativePath), StandardCopyOption.REPLACE_EXISTING);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                });
    } catch (RuntimeException e) {
        throw new IOException("移动文件时出错", e.getCause());
    }
}

2. 复制目录内容

public static void copyDirectoryContents(String sourceDirectory, String targetDirectory, List<String> whiteList) throws IOException {
    Path sourcePath = Paths.get(sourceDirectory);
    Path targetPath = Paths.get(targetDirectory);

    // 确保源存在
    if (!Files.exists(sourcePath)) {
        throw new IOException("源路径不存在: " + sourceDirectory);
    }

    // 如果源是文件
    if (Files.isRegularFile(sourcePath)) {
        Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
        return;
    }

    // 创建目标目录如果不存在
    if (!Files.exists(targetPath)) {
        Files.createDirectories(targetPath);
    }

    // 处理目录复制逻辑
    try {
        Files.walk(sourcePath)
                .filter(path -> !path.equals(sourcePath))
                .filter(path -> whiteList.stream().noneMatch(item -> path.toString().contains(item)))
                .forEach(path -> {
                    try {
                        Path relativePath = sourcePath.relativize(path);
                        Files.copy(path, targetPath.resolve(relativePath), StandardCopyOption.REPLACE_EXISTING);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                });
    } catch (RuntimeException e) {
        throw new IOException("复制文件时出错", e.getCause());
    }
}

逻辑类似于移动文件,但使用 Files.copy 方法。
在复制之前,确保目标目录存在,如果不存在则创建它。

3. 详细讲解 Files.walk()

Files.walk() 是 Java NIO 提供的一个非常强大且灵活的方法,它能够递归地遍历一个目录及其子目录中的所有文件和子目录。下面将详细探讨 Files.walk() 的用法和特性。

1. 方法签名
public static Stream<Path> walk(Path start, int maxDepth, FileVisitOption... options) throws IOException
start: 要开始遍历的目录的路径。
maxDepth: 控制遍历的深度。如果设为 1,只会处理顶级目录;如果设为 2,则会处理顶级目录及其直接子目录,以此类推。如果设为 Integer.MAX_VALUE,则会遍历所有层级的目录。
options: 可选参数,用于指定遍历选项,如 FileVisitOption.FOLLOW_LINKS 允许跟随符号链接。
2. 返回值
Files.walk() 返回一个 Stream<Path>,其中包含遍历到的每个文件和目录的路径。可以使用流的操作(如 filter、map、forEach)对这些路径进行处理。
3. 示例用法

假设我们想要打印某个目录下所有文件的路径,可以这样做:

Path startPath = Paths.get("path/to/directory");
try (Stream<Path> stream = Files.walk(startPath)) {
    stream.filter(Files::isRegularFile)
          .forEach(System.out::println); // 打印所有文件的路径
} catch (IOException e) {
    e.printStackTrace();
}

在这个示例中:

Files.walk(startPath) 开始从 startPath 遍历。
filter(Files::isRegularFile) 过滤掉所有不是普通文件的路径,只保留文件。
forEach(System.out::println) 打印出每个文件的路径。
4. 与 Files.list() 的比较

Files.walk() 与 Files.list() 类似,但 Files.list() 只会返回给定目录的直接子文件和子目录,不会递归遍历下去。因此,使用 Files.walk() 可以更方便地处理层级结构。

二、如何使用 FileUtil

可以在需要批量处理文件的地方调用这些工具方法。示例代码如下:

import java.util.Arrays;

public class FileProcessExample {
    public static void main(String[] args) {
        String sourceDir = "path/to/source";
        String targetDir = "path/to/target";
        List<String> whiteList = Arrays.asList("excludeFile.txt", "excludeDir");

        try {
            // 复制文件
            FileUtil.copyDirectoryContents(sourceDir, targetDir, whiteList);
            System.out.println("文件复制成功!");

            // 移动文件
            FileUtil.moveDirectoryContents(sourceDir, targetDir, whiteList);
            System.out.println("文件移动成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
复制: 使用 copyDirectoryContents 方法,将源目录中的所有文件复制到目标目录中,排除白名单中的文件。
移动: 使用 moveDirectoryContents 方法,将源目录中的文件移动到目标目录中,排除白名单文件。

在实际开发中,合理使用工具类不仅能提高代码的可复用性,还能显著提升开发效率。
如果有任何问题或想要深入了解的内容,欢迎在评论区留言讨论!
源文件

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值