Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ganesh_JavaSE7_Programming_1z0-804_study_guide.pdf
Скачиваний:
94
Добавлен:
02.02.2015
Размер:
5.88 Mб
Скачать

chapter 9 Java File I/O (NIO.2)

if(args.length != 1){

System.out.println("usage: FileDelete <source-path>"); System.exit(1);

}

Path pathSource = Paths.get(args[0]); try {

Files.delete(pathSource); System.out.println("File deleted successfully");

} catch (IOException e) { e.printStackTrace();

}

}

}

It prints the following when executed:

D:\> java FileDelete log.txt File deleted successfully

There are a few points to remember when using the Files.delete() method. In the case of a directory, the delete() method should be invoked on an empty directory; otherwise the method will fail. In the case of a symbolic link, the link will be deleted, not the target file of the link. The file you intend to delete must exist; otherwise you will get a NoSuchFileException. If you silently delete a file and do not want to be bothered about this exception, then you may use the deleteIfExists() method, which will not complain if the file does not exist and deletes it if the file exists.

Walking a File Tree

In various situations, you need to walk through the file tree. For instance, when you want to search a specific file/ directory, you need to walk the file tree. Another example of when you need to walk a file tree is when you want to copy the whole directory containing files/subdirectories.

The Files class provides two methods that let you walk a file tree; the signatures of these methods are given here:

Path walkFileTree(Path start, FileVisitor<? super Path> visitor)

Path walkFileTree(Path start, Set<FileVisitOption> options, int maxDepth, FileVisitor<? super Path> visitor)

Both methods take a path from which the file tree walk will start and an instance of FileVisitor that will govern what you to do while walking a file tree. (We will talk about FileVisitor in detail shortly.) In addition, the second method takes two more parameters: file visit options and maximum depth. The maximum depth parameter specifies the depth of the file tree you wish to visit; a 0 value indicates only the specified file and a MAX_VALUE indicates that all levels of directories must be visited.

Note that you need to supply a FileVisitor instance to the walkFileTree() methods. The FileVisitor interface allows you to perform certain operations at certain key junctures. For instance, the interface provides a visitFile()method that you can implement to specify exactly what needs to be done when the FileVisitor

instance visits a file. Similarly, it also provides three more useful methods, which can be customized based on your needs: preVisitDirectory(), postVisitDirectory(), and visitFileFailed(). Table 9-3 provides a short summary of these methods.

267

chapter 9 Java File i/O (NiO.2)

 

Table 9-3. Methods Supported by the FileVisitor Interface

 

 

 

Method

Description

FileVisitResult preVisitDirectory(T dir, BasicFileAttributes

Invoked just before the elements of the

attrs)

directory are accessed.

FileVisitResult visitFile(T file, BasicFileAttributes attrs)

Invoked when a file is visited.

FileVisitResult postVisitDirectory(T dir, IOException exc)

Invoked when all the elements of the

 

directory are accessed.

FileVisitResult visitFileFailed(T file, IOException exc)

Invoked when the file cannot be accessed.

You need to implement the FileVisitor interface so that you can create an instance of your implementation and pass it to the walkFileTree() methods. However, if you do not want to implement all four methods in the FileVisitor interface, you can simply extend your implementation from the SimpleFileVisitor class. In this way, you can simply override those methods that you want to customize.

Listing 9-12 contains an example so you can understand this more clearly. Assume that you want to print the file tree from a specific point.

Listing 9-12. FileTreeWalk.java

import java.io.IOException; import java.nio.file.*;

import java.nio.file.attribute.BasicFileAttributes;

class MyFileVisitor extends SimpleFileVisitor<Path> {

public FileVisitResult visitFile(Path path, BasicFileAttributes fileAttributes){ System.out.println("file name:" + path.getFileName());

return FileVisitResult.CONTINUE;

}

public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes fileAttributes){ System.out.println("----------Directory name:" + path + "----------");

return FileVisitResult.CONTINUE;

}

}

public class FileTreeWalk {

public static void main(String[] args) { if(args.length != 1) {

System.out.println("usage: FileWalkTree <source-path>"); System.exit(−1);

}

Path pathSource = Paths.get(args[0]); try {

Files.walkFileTree(pathSource, new MyFileVisitor()); } catch (IOException e) {

e.printStackTrace();

}

}

}

268

chapter 9 Java File I/O (NIO.2)

Let’s first execute this program and then understand how it works.

D:\> java FileTreeWalk ch9-13

----------Directory name: ch9-13----------

file name:.classpath file name:.project

----------Directory name: ch9-13\.settings----------

file name:org.eclipse.jdt.core.prefs

----------Directory name: ch9-13\bin----------

file name:FileTreeWalk.class file name:MyFileVisitor.class

----------Directory name: ch9-13\bin\Test----------

file name:log.txt

----------Directory name: ch9-13\src----------

file name:FileTreeWalk.class file name:FileTreeWalk.java file name:MyFileVisitor.class

----------Directory name: ch9-13\src\Test----------

file name:log.txt

We have executed this program with one directory. It printed all the files and directories contained in the given input directory. Now, here’s how it works:

You define a FileVisitor, MyFileVisitor, in which you overrode two methods, visitFile() and preVisitDirectory(), of the SimpleFileVisitor class. In these methods you just printed the name (along with path in case of directory) of the file/directory.

You then invoked walkFileTree() with an instance of MyFileVisitor.

The walkFileTree() method starts from the specified input path. It invokes the visitFile() method when it visits a file, preVisitDirectory() just before it starts visiting the elements of a directory, postVisitDirectory() immediately after it finishes visiting all the elements of the directory, and visitFileFailed() in case any file/directory is not accessible.

Here, since you have overridden two methods, you are able to print the file names and the path of the directories visited.

One more thing that requires attention here is the FileVisitReturn value. You can control the flow of the walk using FileVisitReturn values. There are four types of different return values:

CONTINUE: It indicates that the walk through the file tree should continue.

TERMINATE: It indicates that the walk through the file tree should be terminated immediately.

SKIP_SUBTREE: It indicates that the rest of the subtree should be skipped for the walking file tree.

SKIP_SIBLINGS: It indicates that walking file tree should be stopped for the current directory and its sibling directories. If it is returned from the preVisitDirectory(), then the containing files/directories are not visited and the postVisitDirectory() is also not visited. If it is returned from visitFile(), then no further file in the directory is visited. If it is returned from the postVisitDirectory(), then siblings of the directory are

not visited.

269

chapter 9 Java File I/O (NIO.2)

Revisiting File Copy

You saw how to copy a file from one location to another. However, you couldn’t perform a copy on an entire directory (and its files/subdirectories). Now you can walk through the file tree, making it easier to implement a copy program that can copy the entire directory along with containing elements. Listing 9-13 shows the program to do so.

Listing 9-13.  FileTreeWalkCopy.java

import java.io.IOException; import java.nio.file.*;

import java.nio.file.attribute.*;

// Our File visitor implementation that performs copy class MyFileCopyVisitor extends SimpleFileVisitor<Path> {

private Path source, destination;

public MyFileCopyVisitor(Path s, Path d) { source = s;

destination = d;

}

public FileVisitResult visitFile(Path path, BasicFileAttributes fileAttributes) { Path newd = destination.resolve(source.relativize(path));

try {

Files.copy(path, newd, StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) {

e.printStackTrace();

}

return FileVisitResult.CONTINUE;

}

public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes fileAttributes) { Path newd = destination.resolve(source.relativize(path));

try {

Files.copy(path, newd, StandardCopyOption.REPLACE_EXISTING); }catch (IOException e) {

e.printStackTrace();

}

return FileVisitResult.CONTINUE;

}

}

public class FileTreeWalkCopy {

public static void main(String[] args) { if(args.length != 2) {

System.out.println("usage: FileTreeWalkCopy <source-path> <destination-path>"); System.exit(1);

}

Path pathSource = Paths.get(args[0]); Path pathDestination = Paths.get(args[1]); try {

Files.walkFileTree(pathSource, new MyFileCopyVisitor(pathSource, pathDestination)); System.out.println("Files copied successfully!");

270

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]