Java nio 之 Path

437 阅读2分钟

这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战


Path是在java1.7 nio中新增的用于在文件系统中定位文件的对象。Path由一系列由特殊分隔符或定界符分隔的目录和文件名元素组成,代表了系统中相关文件路径。

Path实现是不可变的,并发编程时可以安全的使用

Path

File不同的是Files通过Path对象对一个文件或者目录的路径进行抽象。Path屏蔽了不同操作系统中路径的不同表示方式。

image.png

创建Path

创建Path需要使用Paths工具类,Paths工具类只有两个重载的get方法用于创建Path。一个是通过多个分隔目录名创建,另一个是使用URI(统一资源标识符)创建。

image.png

示例

image.png

创建子Path

创建子Path使用resolve方法,resolve可以接受一个字符串或者Path类型的参数用于创建子Path

image.png

示例

image.png

这里这是创建一个子Path对象,并未真正创建文件

获取当前的文件系统

image.png

示例

image.png

获取该文件根Path和父Path

image.png

image.png

示例

image.png

获取该path的层级数和对应层级的Path

image.png

image.png

示例 image.png

判断是否是指定开始/结束Path

image.png

image.png

示例

image.png

转成File

image.png

监控文件

通过register方法可以监控文件的变化。register方法接受一个WatchService (从文件系统中获得)和多个StandardWatchEventKinds (文件变动的事件),最后一个参数modifiers用于修改对象的注册方式(可不传)

image.png

image.png

示例

@SneakyThrows
@Test
public void test() {

    Path path = Paths.get("E:", "t");

    WatchService watcher = path.getFileSystem().newWatchService();
    // 监听创建和删除事件
    WatchKey register = path.register(watcher, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE);
    
    // 创建一个线程监控文件的变化
    new Thread(() -> {
        for (; ; ) {
            for (WatchEvent<?> event : register.pollEvents()) {
                System.out.println("文件:" + event.context() + "   kinds: " + event.kind());
            }
            boolean valid = register.reset();
            if (!valid) {
                System.out.println("退出");
                System.exit(0);
            }
        }
    }).start();

    for (int i = 0; i < 10; i++) {
        // 创建文件
        Path file = Files.createFile(path.resolve(i + ".txt"));
        System.out.println("删除: " + file);
        Files.delete(file);
    }
    
}

/*
文件:0.txt   kinds: ENTRY_CREATE
删除: E:\t\0.txt
文件:0.txt   kinds: ENTRY_DELETE
文件:1.txt   kinds: ENTRY_CREATE
删除: E:\t\1.txt
文件:1.txt   kinds: ENTRY_DELETE
文件:2.txt   kinds: ENTRY_CREATE
删除: E:\t\2.txt
文件:2.txt   kinds: ENTRY_DELETE
文件:3.txt   kinds: ENTRY_CREATE
删除: E:\t\3.txt
文件:3.txt   kinds: ENTRY_DELETE
文件:4.txt   kinds: ENTRY_CREATE
删除: E:\t\4.txt
文件:4.txt   kinds: ENTRY_DELETE
文件:5.txt   kinds: ENTRY_CREATE
删除: E:\t\5.txt
删除: E:\t\6.txt
文件:5.txt   kinds: ENTRY_DELETE
文件:6.txt   kinds: ENTRY_CREATE
文件:6.txt   kinds: ENTRY_DELETE
文件:7.txt   kinds: ENTRY_CREATE
删除: E:\t\7.txt
文件:7.txt   kinds: ENTRY_DELETE
文件:8.txt   kinds: ENTRY_CREATE
删除: E:\t\8.txt
文件:8.txt   kinds: ENTRY_DELETE
文件:9.txt   kinds: ENTRY_CREATE
删除: E:\t\9.txt
文件:9.txt   kinds: ENTRY_DELETE
与目标 VM 断开连接, 地址为: ''127.0.0.1:50677',传输: '套接字''

进程已结束,退出代码为 0
*/

Watchservice只会监视给定的目录,而不能监视子目录。如果需要监视整个树目录,必须在整个树的每个子目录上放置一个 Watchservice

文件查找

可以通过path实例获取FileSystem (文件系统)对象,通过调用文件系统的getPathMatcher方法获取匹配路径的对象PathMatchergetPathMatcher支持globregex匹配模式。

image.png

/家/*/*在 UNIX 平台上匹配/home/gus/data这句 home,误译了

示例 image.png

glob开头表示使用glob表达式进行匹配, **/ 表示“当前目录及所有子目录”, * 表示“任何东西”, {} 表示多个匹配项