Reputation: 47
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. 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"
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
Upvotes: 1
Views: 1919
Reputation: 137064
This could be a lot easier to do using Java NIO.2 API in combination with Java 8.
Java 8 introduced the method Files.walk(path)
that returns a Stream of all the paths under a given path, recursively:
Return a
Stream
that is lazily populated withPath
by walking the file tree rooted at a given starting file.
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.
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".
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:
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)
.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).
Upvotes: 1