I am currently getting to grips with file management in Java. As far as i've read, java.nio.file.Path is the preferred way of doing so.
Say I want to copy the contents of oldDir to the, currently empty, newDir. Every time I copy a file, I need this loong line just to get the Path of newFile:
Path newDir = FileSystems.getDefault().getPath("new");
Path oldDir = FileSystems.getDefault().getPath("old");
for (Path oldFile : oldDir) {
Path newFile = FileSystems.getDefault().getPath("new", oldFile.getFileName().toString()); // Why so complicated? :(
Files.copy(oldFile, newFile);
}
Is there something like newDir.getChild(oldFile.getFileName())
to do what I want, or is there really no shorter way of doing it?
There are a couple things you can do to make the code simpler:
Use Path#of(String,String...)
or Paths#get(String,String...)
to create your Path
instances. Both methods delegate to the default FileSystem
. The former was added in Java 11 and is now the preferred approach.
Use Path#resolve(Path)
to append a relative path to some absolute path.
But there's also an error in your code. You are iterating over oldDir
which works because Path
implements Iterable<Path>
. However, that iterates over the names of the path, not the children of the path. In other words, this:
Path path = Path.of("foo", "bar", "file.txt");
for (Path name : path) {
System.out.println(name);
}
Will output:
foo
bar
file.txt
If you want to iterate over the children of a directory you need to use something like Files#list(Path)
or Files#newDirectoryStream(Path)
(the latter has two overloads). Both those methods only return the immediate children of the directory. There are other methods available to recursively iterate a directory and its sub-directories; browse the Files
documentation to see what's provided.
So your code should instead look something like:
Path oldDir = Path.of(...);
Path newDir = Path.of(...);
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(oldDir)) {
for (Path oldFile : dirStream) {
Path newFile = newDir.resolve(oldFile.getFileName());
Files.copy(oldFile, newFile);
}
}