The Java Tutorials have been written for JDK 8.Java教程是为JDK 8编写的。Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.本页中描述的示例和实践没有利用后续版本中引入的改进,并且可能使用不再可用的技术。See Java Language Changes for a summary of updated language features in Java SE 9 and subsequent releases.有关Java SE 9及其后续版本中更新的语言特性的摘要,请参阅Java语言更改。
See JDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.有关所有JDK版本的新功能、增强功能以及已删除或不推荐的选项的信息,请参阅JDK发行说明。
If you have ever used a shell script, you have most likely used pattern matching to locate files. 如果您曾经使用过shell脚本,那么您最有可能使用模式匹配来定位文件。In fact, you have probably used it extensively. 事实上,您可能已经广泛使用了它。If you haven't used it, pattern matching uses special characters to create a pattern and then file names can be compared against that pattern. 如果您没有使用它,模式匹配使用特殊字符来创建模式,然后可以将文件名与该模式进行比较。For example, in most shell scripts, the asterisk, 例如,在大多数shell脚本中,星号*
, matches any number of characters. *
匹配任意数量的字符。For example, the following command lists all the files in the current directory that end in 例如,以下命令列出当前目录中以.html结尾的所有文件:.html
:
% ls *.html
The java.nio.file
package provides programmatic support for this useful feature. java.nio.file
包为这个有用的特性提供了编程支持。Each file system implementation provides a 每个文件系统实现都提供一个PathMatcher
. PathMatcher
。You can retrieve a file system's 您可以使用PathMatcher
by using the getPathMatcher(String)
method in the FileSystem
class. FileSystem
类中的getPathMatcher(String)
方法检索文件系统的PathMatcher
。The following code snippet fetches the path matcher for the default file system:以下代码段获取默认文件系统的路径匹配器:
String pattern = ...; PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
The string argument passed to 传递给getPathMatcher
specifies the syntax flavor and the pattern to be matched. getPathMatcher
的字符串参数指定要匹配的语法风格和模式。This example specifies glob syntax. 本例指定了glob语法。If you are unfamiliar with glob syntax, see What is a Glob.如果您不熟悉glob语法,请参阅什么是glob。
Glob syntax is easy to use and flexible but, if you prefer, you can also use regular expressions, or regex, syntax. Glob语法易于使用且灵活,但如果您愿意,还可以使用正则表达式或正则表达式语法。For further information about regex, see the Regular Expressions lesson. 有关正则表达式的更多信息,请参阅正则表达式课程。Some file system implementations might support other syntaxes.某些文件系统实现可能支持其他语法。
If you want to use some other form of string-based pattern matching, you can create your own 如果希望使用其他形式的基于字符串的模式匹配,可以创建自己的PathMatcher
class. PathMatcher
类。The examples in this page use glob syntax.本页中的示例使用glob语法。
Once you have created your 创建PathMatcher
instance, you are ready to match files against it. PathMatcher
实例后,就可以根据它匹配文件了。The PathMatcher
interface has a single method, matches
, that takes a Path
argument and returns a boolean: It either matches the pattern, or it does not. PathMatcher
接口有一个方法matches
,它接受一个Path
参数并返回一个布尔值:它要么匹配模式,要么不匹配。The following code snippet looks for files that end in 以下代码段查找以.java
or .class
and prints those files to standard output:.java
或.class
结尾的文件,并将这些文件打印到标准输出:
PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.{java,class}"); Path filename = ...; if (matcher.matches(filename)) { System.out.println(filename); }
Searching for files that match a particular pattern goes hand-in-hand with walking a file tree. 搜索与特定模式匹配的文件与遍历文件树密切相关。How many times do you know a file is somewhere on the file system, but where? Or perhaps you need to find all files in a file tree that have a particular file extension.有多少次你知道一个文件在文件系统的某个地方,但是在哪里?或者,您可能需要在文件树中查找具有特定文件扩展名的所有文件。
The Find
example does precisely that. Find
示例正是这样做的。Find
is similar to the UNIX find
utility, but has pared down functionally. Find
类似于UNIX Find
实用程序,但功能有所缩减。You can extend this example to include other functionality. 您可以扩展此示例以包括其他功能。For example, the 例如,find
utility supports the -prune
flag to exclude an entire subtree from the search. find
实用程序支持-prune
标志以从搜索中排除整个子树。You could implement that functionality by returning 您可以通过在SKIP_SUBTREE
in the preVisitDirectory
method. preVisitDirectory
方法中返回SKIP_SUBTREE
来实现该功能。To implement the 要实现符号链接后面的-L
option, which follows symbolic links, you could use the four-argument walkFileTree
method and pass in the FOLLOW_LINKS
enum (but make sure that you test for circular links in the visitFile
method).-L
选项,可以使用四参数walkFileTree
方法并传入FOLLOW_LINKS
枚举(但请确保在visitFile
方法中测试循环链接)。
To run the Find application, use the following format:要运行查找应用程序,请使用以下格式:
% java Find <path> -name "<glob_pattern>"
The pattern is placed inside quotation marks so any wildcards are not interpreted by the shell. 模式放在引号内,因此shell不会解释任何通配符。For example:例如:
% java Find . -name "*.html"
Here is the source code for the 以下是Find
example:Find
示例的源代码:
/** * Sample code that finds files that match the specified glob pattern. * For more information on what constitutes a glob pattern, see * https://docs.oracle.com/javase/tutorial/essential/io/fileOps.html#glob * * The file or directories that match the pattern are printed to * standard out. The number of matches is also printed. * * When executing this application, you must put the glob pattern * in quotes, so the shell will not expand any wild cards: * java Find . -name "*.java" */ import java.io.*; import java.nio.file.*; import java.nio.file.attribute.*; import static java.nio.file.FileVisitResult.*; import static java.nio.file.FileVisitOption.*; import java.util.*; public class Find { public static class Finder extends SimpleFileVisitor<Path> { private final PathMatcher matcher; private int numMatches = 0; Finder(String pattern) { matcher = FileSystems.getDefault() .getPathMatcher("glob:" + pattern); } // Compares the glob pattern against // the file or directory name. void find(Path file) { Path name = file.getFileName(); if (name != null && matcher.matches(name)) { numMatches++; System.out.println(file); } } // Prints the total number of // matches to standard out. void done() { System.out.println("Matched: " + numMatches); } // Invoke the pattern matching // method on each file. @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { find(file); return CONTINUE; } // Invoke the pattern matching // method on each directory. @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { find(dir); return CONTINUE; } @Override public FileVisitResult visitFileFailed(Path file, IOException exc) { System.err.println(exc); return CONTINUE; } } static void usage() { System.err.println("java Find <path>" + " -name \"<glob_pattern>\""); System.exit(-1); } public static void main(String[] args) throws IOException { if (args.length < 3 || !args[1].equals("-name")) usage(); Path startingDir = Paths.get(args[0]); String pattern = args[2]; Finder finder = new Finder(pattern); Files.walkFileTree(startingDir, finder); finder.done(); } }
Recursively walking a file tree is covered in Walking the File Tree.递归遍历文件树将在遍历文件树中介绍。