资讯专栏INFORMATION COLUMN

JAVA NIO.2

TerryCai / 1376人阅读

摘要:会自动遍历下的所有文件和目录,并对其触发中相应的方法,并使用方法的返回值来控制访问器的后续行为。它的实例有继续不访问兄弟文件或目录不访问子文件或子目录终止后续行为官网实例删除所有子文件和子目录是一个接口,定义了监听目录变化的方法。

简介

java 7新增了如下API来访问文件或者进行IO操作

Path - 接口,代表一个平台无关的目录。提供了大量的方法来操作目录。

Paths - 工具类。所有方法都是static的。

Files - 操作文件的工具类。提供了大量的方法来操作文件。该类所包含的大量方法可能与我们日常一般的期望有些出入。

提供以Asynchronous开头的Channel类和接口,因此这部分也可以称为AIO(异步IO)
早期的Java只提供了File类来访问文件,其功能有限且性能不高,NIO.2提供了Path接口以及Paths和Files工具类来访问文件系统。

JAVA AIO

Path、Paths、FileSystems、FileSystem、FileStore、FileStoreAttributeView

java.nio.file.Paths 包含了用于创建Path对象的静态方法
java.nio.file.Path 包含了大量用于操纵文件路径的方法
java.nio.file.FileSystems 用于访问文件系统的类
java.nio.file.FileSystem 代表了一种文件系统,例如Unix下的根目录为 / ,而Windows下则为C盘
java.nio.file.FileStore 代表了真正的存储设备,提供了设备的详尽信息
java.nio.file.attribute.FileStoreAttributeView 提供了访问文件的信息

Path和Paths

代表一个与平台无关的路径。Path是NIO操作的基础,我们可以定义一个文件路径,对路径的相关操作等。

//得到当前目录Path
Path path = Paths.get(".");
//获取绝对路径
Path absulutePath=path.toAbsolutePath();

//得到g:datamoney
Path path = Paths.get("g:","data","money");
  
Files

提供对文件的各种操作的方法

Path path=Paths.get("xxxxxxxx");
//复制文件
Files.copy( path, OutPutStream out);

//判断是否为隐藏文件
boolean isHidden=Files.isHidden(path);

//获取文件大小
long size=Files.size(path);

//写入文件
List list=new ArrayList<>();
Files.write(path, list,Charset.forName("utf-8"));

//操作子目录和子文件
Files.list(path).forEach(path->System.out.println(path));

//等等。。。。。
FileVisitor

在旧版本中遍历文件系统只能通过递归的方法来实现,但是这种方法不仅消耗资源大而且效率低;

NIO.2的Files工具类提供了一个静态工具方法walkFileTree来高效并优雅地遍历文件系统.

walkFileTree(Path start,FileVisitor visitor);
walkFileTree(Path start,Setoptions,int maxDepth,FileVisitor visitor);

FileVisitor就是一个对文件进行操作的文件访问器,它是一个借口,JAVA提供了具体实现类,如SimpleFileVisitor。walkFileTree会自动遍历start下的所有文件和目录,并对其触发FileVisitor中相应的方法,并使用方法的返回值FileVisitResult来控制访问器的后续行为。

//Invoked for a directory after entries in the directory, and all of their descendants, have been visited.
访问该目录及其所有与子文件、子目录后触发
FileVisitResult    postVisitDirectory(T dir, IOException exc)

//Invoked for a directory before entries in the directory are visited.
访问目录前触发
FileVisitResult    preVisitDirectory(T dir, BasicFileAttributes attrs)

//Invoked for a file in a directory.访问文件前触发
FileVisitResult    visitFile(T file, BasicFileAttributes attrs)

//Invoked for a file that could not be visited.
FileVisitResult    visitFileFailed(T file, IOException exc)

//FileVisitResult是一个枚举类型。它的实例有:
1. CONTINUE   //Continue.继续
2. SKIP_SIBLINGS //Continue without visiting the siblings of this file or directory.不访问兄弟文件或目录
3. SKIP_SUBTREE  //Continue without visiting the entries in this directory.//不访问子文件或子目录
4. TERMINATE //Terminate.//终止后续行为

官网实例:删除所有子文件和子目录

 Path start = ...
 Files.walkFileTree(start, new SimpleFileVisitor() {
         @Override
         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
             throws IOException
         {
             Files.delete(file);
             return FileVisitResult.CONTINUE;
         }
         @Override
         public FileVisitResult postVisitDirectory(Path dir, IOException e)
             throws IOException
         {
             if (e == null) {
                 Files.delete(dir);
                 return FileVisitResult.CONTINUE;
             } else {
                 // directory iteration failed
                 throw e;
             }
         }
     });
WatchService

WatchService是一个接口,定义了监听目录变化的方法。

一般来说,我们要监听某个目录的变化(如文件/目录的创建、修改、删除等),会设置一个定时任务(如线程),每隔一分钟读取下指定目录下的文件变化。这种方式很繁琐,而且效率低,效率都消耗在了遍历、保存状态、对比状态上了! 而且无法利用OS的很多功能。

OS自己的文件系统监控器可以监控系统上所有文件的变化,这种监控是无需遍历、无需比较的,是一种基于信号收发的监控,因此效率一定是最高的;现在Java对其进行了包装,可以直接在Java程序中使用OS的文件系统监控器了。

获取监听器:WatchService watcher = FileSystems.getDefault().newWatchService();

注册监听器:
Paths.get("path").register(watchService,StandardWatchEventKinds eventKinds);

WatchService可以监控文件的变动信息(监控到文件是修改,新增、删除等事件;)
其中注册事件有的:
StandardWatchEventKinds.ENTRY_MODIFY,//更新
StandardWatchEventKinds.ENTRY_DELETE,//创建
StandardWatchEventKinds.ENTRY_CREATE,//删除

监听器的方法(关闭、获取事件通知):
1. void    close() //关闭监听器
Closes this watch service.
2. WatchKey    poll() //获取下一个WatchKey,如果没有则返回null
Retrieves and removes the next watch key, or null if none are present.
3. WatchKey    poll(long timeout, TimeUnit unit) //尝试等待一段时间,获取下一个WatchKey
Retrieves and removes the next watch key, waiting if necessary up to the specified wait time if none are yet present.
4. WatchKey    take()  //如果没有WatchKey就一直等待
Retrieves and removes next watch key, waiting if none are yet present.

实例:

WatchService watcher = FileSystems.getDefault().newWatchService();
Paths.get("path").register(watchService,StandardWatchEventKinds StandardWatchEventKinds.ENTRY_DELETE);//监听子文件或子目录的创建事件

while(true){
    WatchKey key = watcher.take();  
    for (WatchEvent event: key.pollEvents()) {  
        System.out.println(event.context() + " comes to " + event.kind());  
    }  
      
    boolean valid = key.reset();  
    if (!valid) {  
        break;  
    }  
}

reference:
流与文件NIO.2
java利用WatchService实时监控某个目录下的文件变化并按行解析

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/67908.html

相关文章

  • java-netty-Netty in Action 5th-ch1-Netty and Java

    摘要:一个多路复用器可以负责成千上万的通道,没有上限。不需要通过对多路复用器对注册的通道进行轮询操作即可实现异步读写,从而简化编程模型。同时,支持支持如果是怎么办最后,到目前位置,支持不支持二无法扩展作为的核心,无法扩展,私有构造函数。 前言 netty 学习 基于 netty in action 5th, 官网资料,网络博客等 1.1 Why Netty? netty 是一个中间层的抽象 ...

    LeviDing 评论0 收藏0
  • Java NIO

    摘要:缓冲区的容量不可能为负值,创建后不能改变界限界限第一个不应该被读写或者写入的缓冲区位置索引。当使用从中读取数据时,的值恰好等于已经读到了多少数据。 NIO:New IO Java新IO概述 新IO采用内存映射文件的方式来处理输入/输出,新IO文件或文件的一段区域映射到内存中,这样就可以访问内存一样来访问文件了(这种方式模拟了操作系统上的虚拟内存的概念),通过这种方式来进行输入/输出比传...

    Steve_Wang_ 评论0 收藏0
  • 一文理解:Java NIO 核心组件

    摘要:的出现解决了这尴尬的问题,非阻塞模式下,通过,我们的线程只为已就绪的通道工作,不用盲目的重试了。注意要将注册到,首先需要将设置为非阻塞模式,否则会抛异常。 showImg(https://segmentfault.com/img/remote/1460000017053374); 背景知识 同步、异步、阻塞、非阻塞 首先,这几个概念非常容易搞混淆,但NIO中又有涉及,所以总结一下。 ...

    Coding01 评论0 收藏0
  • 一文让你彻底理解 Java NIO 核心组件

    摘要:的出现解决了这尴尬的问题,非阻塞模式下,通过,我们的线程只为已就绪的通道工作,不用盲目的重试了。注意要将注册到,首先需要将设置为非阻塞模式,否则会抛异常。 同步、异步、阻塞、非阻塞首先,这几个概念非常容易搞混淆,但NIO中又有涉及,所以总结一下[1]。 同步:API调用返回时调用者就知道操作的结果如何了(实际读取/写入了多少字节)。 异步:相对于同步,API调用返回时调用者不知道操作...

    guyan0319 评论0 收藏0
  • Linux I/O model 和 JAVA NIO/AIO

    摘要:之后推出的是,是面向缓冲区的,数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。之后的又引入了,对应的可以实现模式。该接口常被用于高效的网络文件的数据传输和大文件拷贝。进阶五模型从到和模式 Linux I/O model blocking I/O non blocking I/O I/O multiplexing (select and poll) signal driv...

    Zack 评论0 收藏0

发表评论

0条评论

TerryCai

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<