Copying a folder

In order to copy a file, we can rely on the Path copy​(Path source, Path target, CopyOption options) throws IOException method. This method copies a file to the target file with the options parameter specifying how the copy is performed.

By combining the copy() method with a custom FileVisitor, we can copy an entire folder (including all its content). The stub code of this custom FileVisitor is listed as follows:

public class CopyFileVisitor implements FileVisitor {

private final Path copyFrom;
private final Path copyTo;
...

private static void copySubTree(
Path copyFrom, Path copyTo) throws IOException {

Files.copy(copyFrom, copyTo,
REPLACE_EXISTING, COPY_ATTRIBUTES);
}
}

Let's take a look at the main checkpoints and the implementation of copying a folder (note that we will act indulgently by copying anything that we can and avoid throwing exceptions, but feel free to adapt the code to suit your needs):

  • Before copying any files from a source folder, we need to copy the source folder itself. Copying a source folder (empty or not) will result in an empty target folder. This is the perfect task to accomplish in the preVisitDirectory() method:
@Override
public FileVisitResult preVisitDirectory(
Object dir, BasicFileAttributes attrs) throws IOException {

Path newDir = copyTo.resolve(
copyFrom.relativize((Path) dir));

try {
Files.copy((Path) dir, newDir,
REPLACE_EXISTING, COPY_ATTRIBUTES);
} catch (IOException e) {
System.err.println("Unable to create "
+ newDir + " [" + e + "]");

return FileVisitResult.SKIP_SUBTREE;
}

return FileVisitResult.CONTINUE;
}
  • The visitFile() method is the perfect place to copy each file:
@Override
public FileVisitResult visitFile(
Object file, BasicFileAttributes attrs) throws IOException {

try {
copySubTree((Path) file, copyTo.resolve(
copyFrom.relativize((Path) file)));
} catch (IOException e) {
System.err.println("Unable to copy "
+ copyFrom + " [" + e + "]");
}

return FileVisitResult.CONTINUE;
}
  • Optionally, we can preserve the attributes of the source directory. This can be accomplished only after the files have been copied into the postVisitDirectory() method (for example, let's preserve the last modified time):
@Override
public FileVisitResult postVisitDirectory(
Object dir, IOException ioe) throws IOException {

Path newDir = copyTo.resolve(
copyFrom.relativize((Path) dir));

try {
FileTime time = Files.getLastModifiedTime((Path) dir);
Files.setLastModifiedTime(newDir, time);
} catch (IOException e) {
System.err.println("Unable to preserve
the time attribute to: " + newDir + " [" + e + "]");
}

return FileVisitResult.CONTINUE;
}
  • If a file cannot be visited, then visitFileFailed() will be invoked. This is a good moment to detect circular links and report them. By following links (FOLLOW_LINKS), we can encounter cases where the file tree has a circular link to a parent folder. These cases are reported via FileSystemLoopException exceptions in visitFileFailed():
@Override
public FileVisitResult visitFileFailed(
Object file, IOException ioe) throws IOException {

if (ioe instanceof FileSystemLoopException) {
System.err.println("Cycle was detected: " + (Path) file);
} else {
System.err.println("Error occured, unable to copy:"
+ (Path) file + " [" + ioe + "]");
}

return FileVisitResult.CONTINUE;
}

Let's copy the D:/learning/packt folder to D:/e-courses:

Path copyFrom = Paths.get("D:/learning/packt");
Path copyTo = Paths.get("D:/e-courses");

CopyFileVisitor copyFileVisitor
= new CopyFileVisitor(copyFrom, copyTo);

EnumSet opts = EnumSet.of(FileVisitOption.FOLLOW_LINKS);

Files.walkFileTree(copyFrom, opts, Integer.MAX_VALUE, copyFileVisitor);
By combining CopyFileVisitor and DeleteFileVisitor, we can easily shape an application for moving folders. In the code bundled with this book, there is a complete example of moving folders as well. Based on the expertise we've accumulated so far, the code should be pretty accessible without further details.

Pay attention when logging information regarding files (for example, as in the case of handling exceptions) since files (for example, their names, paths, and attributes) may contain sensitive information that can be exploited in a malicious fashion.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset