Java - 在文件系统中移动文件

Java - Moving files within filesystem

我正在做学校作业,我们正在做简单的文件管理器,它应该将所有后缀为 "jpg" 的文件(例如)移动到另一个文件夹中。问题是我们应该递归地遍历所有文件夹。

示例:您在文件夹 "downloads" 中:

--downloads
----me.jpg
----smth.doc
----folder1
------you.jpg

现在您必须将所有 .jpg 文件移动到文件夹 "photos" 并在那里创建 "folder1" 并移动文件 "you.jpg"

这就是我所拥有的,但它似乎只移动了 "downloads folder"

中的文件
private void move(String suffix, String sourcePath, String destination) throws IOException{
    File dir = new File(sourcePath);
    File destDir = new File(destination);
    String src;
    String dst;

    for (File f : dir.listFiles(new ExtensionFilter(suffix))){
        String name = f.getName();
        src = f.getAbsolutePath();
        dst = destination + "\" + name;
        Files.createDirectories(Paths.get(destination));
        Files.move(Paths.get(src), Paths.get(dst));
        logs.add("MV;" + src + ";" + dst);
    }

    for (File f : dir.listFiles(new DirectoryFilter())){
        move(suffix, f.getPath(), destination + "\" + f.getName());    
    }
}

logs 就是 ArrayList 用来保存哪些文件被移动的日志

尝试使用来自 Apache Commons IO 的 FileUtils。这是最简单的方法。

Java NIO.2 API 与 Java 8.

结合使用可能会容易得多

Java 8 引入了方法Files.walk(path),即returns一个给定路径下所有路径的Stream,递归:

Return a Stream that is lazily populated with Path by walking the file tree rooted at a given starting file.

建议的解决方案如下:

private void move(String suffix, Path source, Path destination) throws IOException {
    Files.createDirectories(destination);
    Files.walk(source)
         .filter(p -> p.toString().endsWith(suffix))
         .forEach(p -> {
             Path dest = destination.resolve(source.relativize(p));
             try {
                 Files.createDirectories(dest.getParent());
                 Files.move(p, dest);
             } catch (IOException e) {
                 throw new UncheckedIOException(e);
             }
         });
}

此代码创建目标路径。然后它从源路径开始,只过滤以给定后缀结尾的路径。最后,对于他们每个人:

  • source.relativize(p) returns 从源到此路径的相对路径。

    For example, on UNIX, if this path is "/a/b" and the given path is "/a/b/c/d" then the resulting relative path would be "c/d".

    因此,这将return源路径下的部分路径,以便我们可以将其复制到目标路径中。

  • destination.resolve(other) returns 通过将此路径附加到其他路径构建的路径:

    In the simplest case, [...], in which case this method joins the given path to this path and returns a resulting path that ends with the given path.

  • 所以现在,我们实际上拥有了完整的目标路径。我们首先需要使用 Files.createDirectories(dir). dest.getParent() returns the parent path, that is to say, it drops the filename from the path. The final step is moving the source path to the target path with Files.move(source, target).
  • 创建父目录

如果您还不能升级到 Java 8 并继续使用 Java 7,您仍然可以使用 Files.walkFileTree 而不是 Files.walk(其余的代码需要调整,但思路是一样的)。