Java 文件树
Java IO教程 - Java文件树
FileVisitor API可以递归地处理文件树中的所有文件和目录。
当我们要对文件树中的所有或某些文件或目录执行某些操作时,FileVisitor API非常有用。
SimpleFileVisitor类是FileVisitor接口的基本实现。
当访问文件/目录时,SimpleFileVisitor类不执行任何操作。我们可以从SimpleFileVisitor类继承我们的文件访问类,并且只覆盖适合我们需要的方法。
FileVisitor接口的方法:
ID | 含义 |
---|---|
1 | FileVisitResult preVisitDirectory(T dir,BasicFileAttributes attrs) 在访问目录中的条目之前调用一次。 |
2 | FileVisitResult postVisitDirectory(T dir,IOException exc) 已访问目录中的后调用项。如果在目录的迭代期间抛出了任何异常,则将异常对象作为第二个参数传递给此方法。如果此方法的第二个参数为null,则在目录迭代期间没有异常。 |
3 | FileVisitResult visitFile(T文件,BasicFileAttributes attrs) 当访问目录中的文件时调用。 |
4 | FileVisitResult visitFileFailed(T文件,IOException exc) 当由于任何原因而无法访问文件或目录时调用。 |
下表列出了FileVisitResult的枚举常量及其说明
枚举常量 | 描述 |
---|---|
CONTINUE | 继续处理 |
SKIP_SIBLINGS | 继续处理而不访问文件或目录的兄弟节点。 |
SKIP_SUBTREE | 继续处理,而不访问目录中的条目。 |
TERMINATE | 终止文件访问过程。 |
我们不需要在我们的文件访问类的所有四个方法中编写逻辑。要复制目录,请使用preVisitDirectory()方法来创建一个新目录和visitFile()方法来复制文件。
以下代码显示如何打印目录的子目录和文件的名称。
import static java.nio.file.FileVisitResult.CONTINUE; import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; public class Main { public static void main(String[] args) { Path startDir = Paths.get(""); FileVisitor<Path> visitor = getFileVisitor(); try { Files.walkFileTree(startDir, visitor); } catch (IOException e) { e.printStackTrace(); } } public static FileVisitor<Path> getFileVisitor() { class DirVisitor<Path> extends SimpleFileVisitor<Path> { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { System.out.format("%s [Directory]%n", dir); return CONTINUE; } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { System.out.format("%s [File, Size: %s bytes]%n", file, attrs.size()); return CONTINUE; } } FileVisitor<Path> visitor = new DirVisitor<>(); return visitor; } }
上面的代码生成以下结果。
例子
以下代码显示如何使用FileVisitor API删除目录树。
import static java.nio.file.FileVisitResult.CONTINUE; import static java.nio.file.FileVisitResult.TERMINATE; import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; public class Main { public static void main(String[] args) { Path dirToDelete = Paths.get("DIR"); FileVisitor<Path> visitor = getFileVisitor(); try { Files.walkFileTree(dirToDelete, visitor); } catch (IOException e) { System.out.println(e.getMessage()); } } public static FileVisitor<Path> getFileVisitor() { class DeleteDirVisitor extends SimpleFileVisitor<Path> { @Override public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException { FileVisitResult result = CONTINUE; if (e != null) { System.out.format("Error deleting %s. %s%n", dir, e.getMessage()); result = TERMINATE; } else { Files.delete(dir); System.out.format("Deleted directory %s%n", dir); } return result; } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Files.delete(file); System.out.format("Deleted file %s%n", file); return CONTINUE; } } FileVisitor<Path> visitor = new DeleteDirVisitor(); return visitor; } }
上面的代码生成以下结果。
例2
以下代码显示如何使用walkFileTree()方法跟随符号链接。
import java.nio.file.FileVisitOption; import java.nio.file.FileVisitor; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.EnumSet; import java.util.Set; import static java.nio.file.FileVisitOption.FOLLOW_LINKS; public class Main { public static void main(String[] args) throws Exception { Path startDir = Paths.get(""); FileVisitor<Path> visitor = create your visitor; Set<FileVisitOption> options = EnumSet.of(FOLLOW_LINKS); int depth = Integer.MAX_VALUE; Files.walkFileTree(startDir, options, depth, visitor); } }
模式匹配
我们可以使用glob和正则表达式模式对字符串形式的Path对象执行模式匹配。
功能接口PathMatcher用于执行匹配。它包含一个方法matches(Path path)方法,如果指定的路径匹配模式,则该方法返回true。
模式字符串由两部分组成,语法和模式由冒号分隔:
syntax:pattern
语法的值是glob或regex。模式部分遵循取决于语法部分的值的语法。
glob模式使用以下语法规则:
- * 匹配零个或多个字符,而不会交叉目录边界。
- ** 匹配零个或多个字符跨目录边界。
- ? 只匹配一个字符。
- \ 转义以下字符的特殊含义。
- \\ 匹配单个反斜杠。
- \* 匹配星号。
放在括号 []
中的字符称为括号表达式,它匹配单字符。[aeiou]匹配a,e,i,o或u。
两个字符之间的破折号指定范围。[a-z]匹配a和z之间的所有字母。
左括号后的感叹号(!)被视为否定。[!abc]匹配除a,b和c之外的所有字符。
通过在大括号({})中指定逗号分隔的子模式来使用一组子模式。例如,{txt,java,doc}匹配txt,java和doc。
路径的根组件的匹配是实现相关的。
以下代码显示了如何使用PathMatcher对象将路径与glob模式匹配。
import java.nio.file.FileSystems; import java.nio.file.Path; import java.nio.file.PathMatcher; import java.nio.file.Paths; public class Main { public static void main(String[] args) { String globPattern = "glob:**txt"; PathMatcher matcher = FileSystems.getDefault().getPathMatcher(globPattern); Path path = Paths.get("C:\\Java_Dev\\test1.txt"); boolean matched = matcher.matches(path); System.out.format("%s matches %s: %b%n", globPattern, path, matched); } }
上面的代码生成以下结果。
更多建议: