目录访问的四种方式
1. Files.list
类: java.nio.file.Files
函数声明:
static Stream<Path> list(Path path) throws IOEXception
作用:遍历特定目录,并返回包含该目录下项目的Path流,目录是被惰性读取的,因此不会读取子目录.
注意:读取目录涉及需要关闭系统资源,所以应该使用try块.
例子:
import java.nio.file.Paths;
import java.text.DecimalFormat;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class DirList {
public static void main(String[] args) throws IOException {
//list方法不会进入子目录
try(Stream<Path> entries = Files.list (Paths.get ("D:\\Java"))){
entries.forEach (System.out::println);
}
}
}
2. Files.newDirectoryStream
类: java.nio.file.Files
函数声明:
public static DirectoryStream<Path> newDirectoryStream(Path dir) throws IOException
第二个参数代表glob模式,即匹配项.
static DirectoryStream<Path> newDirectoryStream(Path dir, String glob)
Glob模式
模式 | 描述 | 示 例 |
---|---|---|
* |
匹配路径组成部分中0个或多个字符 | *.java 匹配所有的java文件 |
** |
匹配跨目录边界的0个或多个字符 | **.java 匹配在所有子目录的java文件 |
? | 匹配一个字符 | ????.java 匹配四个字符的java文件 |
[...] |
匹配一个字符集合 | 正则表达式 |
{...} |
匹配由逗号隔开的多个可选项之一 | *.{java,class} 匹配所有的java文件和class文件 |
\ |
转义上述字符和\字符 | \\\\匹配\ |
static DirectoryStream<Path> newDirectoryStream(Path dir, DirectoryStream.Filter<? super Path> filter)
作用:遍历特定目录,生成一个目录流,DirectoryStream是一个单独的类,不是继承自Stream<?>,结果中只包含当前目录下的Path.
3. Files.walk
类: java.nio.file.Files
函数声明:
static Stream<Path> walk(Path start, int maxDepth, FileVisitOption... options)
其中maxDepth可以控制访问的深度。
FileVisitOption的枚举值:FOLLOW_LINKS ,也可以用FileVisitOption.valueOf(String option)生成。
作用:会产生一个可以遍历目录中左右子目录的Stream
4. Files.walkFileTree
类 : java.nio.file.Files
函数声明:
public static Path walkFileTree(Path start, FileVisitor<? super Path> visitor) throws IOException
SimpleFileVisitor类实现了FileVisitor<? extends visitor>接口。
作用:访问某个目录的所有子孙成员,并向其换第一个FileVisitor<>类型的对象,这个对象会得到如下通知:
-
遇到一个文件或目录时:
FileVisitResult visitFile(Path path,BasicFileAttributes attrs)
-
在一个目录被处理后:
FileVisitResult postVisitDirectory(Path path,IOException e)
-
在一个目录被处理前:
FileVisitResult preVisitDirectory(Path path,IOException e)
-
试图访问文件或者目录时发生错误:
FileVisitResult visitFileFailed(Path path,IOException e)
对每种情况,都可以制定实行下面的操作,并通过返回值的方式返回:
- 继续访问下一个文件:FileVisitResult.CONTINUE
- 继续访问,但不访问该目录下的任何一项:FileVisitResult.SKIP_SUBTREE
- 继续访问,但不再访问该文件或目录的兄弟文件或目录:FileVisitResult.SKIP_SIBLINGS
- 终止访问,FileVisitResult.TERMINATE
在使用时,要重载这些方法。
例子:访问所有内容
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
public class WalkTreeTest {
public static void main(String[] args) throws IOException {
Files.walkFileTree (Paths.get("D:\\Java"),new SimpleFileVisitor<Path> (){
//遇到一个文件前
@Override
public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes attrs){
System.out.println (path);
return FileVisitResult.CONTINUE;
}
//遇到一个文件后
@Override
public FileVisitResult postVisitDirectory(Path path,IOException e){
return FileVisitResult.CONTINUE;
}
//访问文件失败,跳过
@Override
public FileVisitResult visitFileFailed(Path path,IOException e){
return FileVisitResult.SKIP_SUBTREE;
}
});
}
}
例子:删除文件夹及所有子项
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.stream.Stream;
public class DeleteDirectory {
public static void main(String[] args) throws IOException {
Files.exists (Paths.get ("1/2/3/4/5/6/7"));
Files.deleteIfExists (Paths.get ("1/2/3/4/5/6/7"));
Files.createDirectories (Paths.get ("1/2/3/4/5/6/7"));
// try(DirectoryStream<Path> directoryStream = Files.newDirectoryStream (Paths.get ("1"))){
// directoryStream.forEach (x -> System.out.println ("创建目录:" + x.toString () + "成功."));
// }
try(Stream<Path> stream = Files.walk (Paths.get ("1"))){
stream.forEach (x -> System.out.println ("目录" + x + "已被创建."));
}
System.out.println ("下面开始删除目录.");
Files.walkFileTree (Paths.get ("1"),new SimpleFileVisitor<> (){
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
Files.deleteIfExists (path);
System.out.println (path + "已被删除.");
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path path,IOException e) throws IOException{
if (e != null)
throw e;
Files.deleteIfExists (path);
System.out.println (path + "已被删除.");
return FileVisitResult.CONTINUE;
}
});
}
}