目录访问的四种方式

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;
            }
        });
    }
}