Java NIO 学习笔记(五)----路径、文件和管道 Path/Files/Pipe (2)

注意:复制文件夹的时候,只能复制空文件夹,如果文件夹非空,需要递归复制,否则只能得到一个空文件夹,而文件夹里面的文件不会被复制。

移动文件/文件夹

只有 1 个移动文件或文件夹的方法:

static Path move(Path source, Path target, CopyOption... options);

如果文件是符号链接,则移动符号链接本身,而不是符号链接指向的实际文件。
和移动文件一样,也存在第三个可选参数 CopyOption ,参考上述。如果移动文件失败,可能会抛出 IOException,例如,如果文件已存在于目标路径中,并且遗漏了覆盖选项,或者要移动的源文件不存在等。

和复制文件夹不一样,如果文件夹里面有内容,复制只会复制空文件夹,而移动会把文件夹里面的所有东西一起移动过去,以下是一个移动文件夹的示例:

// 移动 s 目录到一个不存在的新目录 Path s = Paths.get("D:\\s"); Path d = Paths.get("D:\\test\\test"); Files.createDirectories(d.getParent()); Files.move(s, d);

和 Linux mv 命令一样,重命名文件与移动文件方式相同,移动文件还可以将文件移动到不同的目录并可以同时更改其名称。 另外 java.io.File 类也可以使用它的 renameTo() 方法来实现移动文件,但现在 java.nio.file.Files 类中也有文件移动功能。

删除文件/文件夹 static void delete(Path path); static boolean deleteIfExists(Path path); // 如果文件被此方法删除则返回 true

如果文件是目录,则该目录必须为空才能删除。

Files.walkFileTree() 静态方法

删除和复制文件夹的时候,如果文件夹为空,那么会删除失败或者只能复制空文件夹,此时可以使用 walkFileTree() 方法进行遍历文件树,然后在 FileVisitor 对象的 visitFile() 方法中执行删除或复制文件操作。
Files 类有 2 个重载的 walkFileTree() 方法,如下:

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

将 Path 实例和 FileVisitor 作为参数,walkfiletree() 方法可以递归遍历目录树。Path 实例指向要遍历的目录。在遍历期间调用 FileVisitor ,首先介绍 FileVisitor 接口:

public interface FileVisitor<T> { FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs) throws IOException; FileVisitResult visitFile(T file, BasicFileAttributes attrs) throws IOException; FileVisitResult visitFileFailed(T file, IOException exc) throws IOException; FileVisitResult postVisitDirectory(T dir, IOException exc) throws IOException; }

必须自己实现 FileVisitor 接口,并将其实现的实例传递给 walkFileTree() 方法。在目录遍历期间,将在不同的时间调用 FileVisitor 实现的 4 个方法,代表对遍历到的文件或目录进行什么操作。如果不需要使用到所有方法,可以扩展 SimpleFileVisitor 类,该类包含 FileVisitor 接口中所有方法的默认实现。

Files.walkFileTree(inputPath, new FileVisitor<Path>() { // 访问文件夹之前调用此方法 @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { System.out.println("pre visit dir:" + dir); return FileVisitResult.CONTINUE; } // 访问的每个文件都会调用此方法,只针对文件,不会对目录执行 @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { return FileVisitResult.CONTINUE; } // 访问文件失败会调用此方法,只针对文件,不会对目录执行 @Override public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { return FileVisitResult.CONTINUE; } // 访问文件夹之后会调用此方法 @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { return FileVisitResult.CONTINUE; } });

这四个方法都返回一个 FileVisitResult 枚举实例。FileVisitResult 枚举包含以下四个选项:

CONTINUE : 继续

TERMINATE : 终止

SKIP_SIBLINGS : 跳过兄弟节点,然后继续

SKIP_SUBTREE : 跳过子树(不访问此目录的条目),然后继续,仅在 preVisitDirectory 方法返回时才有意义,除此以外和 CONTINUE 相同。

通过返回其中一个值,被调用的方法可以决定文件遍历时接下来应该做什么。

搜索文件

walkFileTree() 方法还可以用于搜索文件,下面这个例子扩展了 SimpleFileVisitor 来查找一个名为 input.txt 的文件:

Path rootPath = Paths.get("D:\\test"); String fileToFind = File.separator + "input.txt"; Files.walkFileTree(rootPath, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { String fileString = file.toAbsolutePath().toString(); System.out.println("pathString: " + fileString); if (fileString.endsWith(fileToFind)) { System.out.println("file found at path: " + fileString); return FileVisitResult.TERMINATE; } return FileVisitResult.CONTINUE; } });

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsszwj.html