简体   繁体   English

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

[英]Java - Moving files within filesystem

I am working on school assignment and we are doing simple filemanager that should move all files with suffix "jpg" (for example) into another folder. 我正在做学校作业,我们正在做一个简单的filemanager,它将所有带后缀"jpg"文件(例如)移到另一个文件夹中。 Problem is that we should do it recursively through all the folders. 问题是我们应该对所有文件夹进行递归操作。

Example: you are in folder "downloads": 示例:您在文件夹“下载”中:

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

and now you have to move all .jpg files into folder "photos" and create "folder1" there and also move file "you.jpg" 现在,您必须将所有.jpg文件移动到文件夹“照片”中,并在其中创建“ folder1”,同时还要移动文件“ you.jpg”

This is what I have but it seems to move only files from "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 is just ArrayList to save log which files have been moved 日志只是ArrayList来保存已移动文件的日志

Try using FileUtils from Apache Commons IO. 尝试从Apache Commons IO使用FileUtils That's the easiest way. 那是最简单的方法。

This could be a lot easier to do using Java NIO.2 API in combination with Java 8. 结合使用Java NIO.2 API和Java 8,可能会容易得多

Java 8 introduced the method Files.walk(path) that returns a Stream of all the paths under a given path, recursively: Java 8引入了Files.walk(path)方法,该方法Files.walk(path)返回给定路径下所有路径的Stream:

Return a Stream that is lazily populated with Path by walking the file tree rooted at a given starting file. 通过遍历以给定起始文件为根的文件树,返回用Path懒散填充的Stream

A proposed solution could then be the following: 建议的解决方案如下:

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

This code creates the destination path. 此代码创建目标路径。 Then it walks starting from the source path and filters only the paths that ends with the given suffix. 然后,它从源路径开始走,并仅过滤以给定后缀结尾的路径。 Finally, for each of them: 最后,对于每个人:

  • source.relativize(p) returns the relative path from the source to this path. source.relativize(p)返回从源到该路径的相对路径。

    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". 例如,在UNIX上,如果此路径为“ / a / b”并且给定路径为“ / a / b / c / d”,则所得的相对路径将为“ c / d”。

    As such, this will return the part of the path under the source so that we can copy it into the target path. 这样,这将返回路径在源下的部分,以便我们可以将其复制到目标路径中。

  • destination.resolve(other) returns the path constructed by appending this path to the other path: destination.resolve(other)返回通过将此路径附加到其他路径而构建的路径:

    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. 在最简单的情况下,在这种情况下,此方法将给定路径连接到该路径,并返回以给定路径结尾的结果路径。

  • So now, we effectively have the full target path. 因此,现在,我们有效地拥有了完整的目标路径。 We first need to create the parent directories with Files.createDirectories(dir) . 我们首先需要使用Files.createDirectories(dir)创建父目录。 dest.getParent() returns the parent path, that is to say, it drops the filename from the path. dest.getParent()返回父路径,也就是说,它将路径中的文件名删除。 The final step is moving the source path to the target path with Files.move(source, target) . 最后一步是使用Files.move(source, target)将源路径移动到目标路径。

If you can't upgrade to Java 8 yet and keep with Java 7, you can still use Files.walkFileTree instead of Files.walk (the rest of the code would need adjustment but the idea is the same). 如果您还不能升级到Java 8并继续使用Java 7,则仍然可以使用Files.walkFileTree而不是Files.walk (其余代码需要进行调整,但是想法是相同的)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM