Java7对NIO进行了大的改进,新增了许多功能:java
这些新增的IO功能简称为 NIO.2,依然在java.nio包下。安全
早期的Java只提供了File类来操做文件、文件夹自己,功能有限,性能也不高。异步
NIO.2为解决这种缺陷,提供了Path接口,并提供了Paths、Files2个工具类,这2个工具类包含的方法都是静态方法,Files类提供了大量的静态方法来操做文件、文件夹。工具
Path接口、Paths工具类使用示例:性能
1 //获取指定路径的Path对象 2 Path path=Paths.get("D:/untitled/test/"); 3 //也能够这样写: Path path=Paths.get("D","untitled","test"); 参数个数可变 4 5 //返回文件/文件夹名,test 6 System.out.println(path.getFileName()); 7 //返回父目录的路径,D:\untitled 8 System.out.println(path.getParent()); 9 //判断该路径的最后一级是不是指定的文件/文件夹,true。和String的endsWith有点不一样。当参数是最后一级的文件/文件夹名时,才返回true。 10 System.out.println(path.endsWith("test")); 11 //以上方法的操做对象是Path对象中的路径,就是说路径没必要是真实存在的 12 13 //返回根路径(盘符),D:\ 14 System.out.println(path.getRoot()); 15 //返会绝对路径 16 System.out.println(path.toAbsolutePath()); 17 //以上获取的路径要是真实存在的
之前,若是要监控文件、目录的变化(新建、修改、删除),通常是启动一条后台线程,这条线程每隔一段时间去遍历指定目录的文件,若是这次遍历的结果与上次遍历的结果不一样,就认为文件发生了变化。这种方式很繁琐,性能也低。测试
NIO.2的Path接口提供了一个方法来监听文件变化:spa
register(WatchService watcher, 要监听的事件类型1,要监听的事件类型2,.......) //注册一个监听服务线程
好比“xx安全卫士提醒您:xx程序将建立xx文件,是否容许?”、“xx程序试图修改xx文件,是否容许?”,就可以使用此方法实现。code
使用示例:对象
1 public class Test { 2 public static void main(String[] args) throws IOException, InterruptedException { 3 4 //建立一个文件系统的监听服务 5 WatchService watchService= FileSystems.getDefault().newWatchService(); 6 7 Path path=Paths.get("D:/untitled/test"); 8 9 //为该文件夹注册监听,监听新建、修改、删除事件。只能为文件夹(目录)注册监听,不能为单个文件注册监听 10 path.register(watchService,StandardWatchEventKinds.ENTRY_CREATE,StandardWatchEventKinds.ENTRY_MODIFY,StandardWatchEventKinds.ENTRY_DELETE); 11 12 //编写事件处理 13 while (true){ //一直监听 14 //拉取一个WatchKey。当触发监听的事件时,就会产生一个WatchKey,此WatchKey封装了事件信息。 15 WatchKey watchKey=watchService.take(); 16 17 //使用循环是由于这一个WatchKey中可能有多个文件变化了,好比Ctrl+A全选,而后删除,只触发了一个WatchKey,但有多个文件变化了 18 for (WatchEvent event:watchKey.pollEvents()){ 19 System.out.println(event.context()+"发生了"+event.kind()+"事件!"); 20 /* 21 watchKey.pollEvents() 获取这次WatchKey中全部变化了的文件的信息,以List(列表)形式返回,一个WatchEvent就是一个元素,封装了一个变化了的文件的信息 22 event.context() 获取文件名 23 event.kind() 获取发生的事件类型 24 25 由于只能为文件夹注册监听,若是要监听某些指定的文件,能够在加强的for循环中,先根据event.context()判断是不是指定的文件,是才处理。 26 */ 27 } 28 29 //虽然是while()循环,但WatchKey和ByteBuffer同样,使用完要重置状态,才能继续用。 30 watchKey.reset(); //若是不重置,WatchKey使用一次事后就不能再使用,即只能监听到一次文件变化。 31 } 32 33 34 /* 35 测试:在D:/untitled/test目录下 36 一、新建1.txt文件 1.txt.txt发生了ENTRY_CREATE事件! 37 二、打开1.txt,输入"hello world!",并保存 1.txt.txt发生了ENTRY_MODIFY事件! 38 三、删除“hello world!",并保存 1.txt.txt发生了ENTRY_MODIFY事件! 39 四、新建2.txt文件 2.txt发生了ENTRY_CREATE事件! 40 41 说明:编辑文件内容时,不算修改,保存时才算修改。 42 43 五、新建文件夹“图片” 44 新建文件夹发生了ENTRY_CREATE事件! 45 新建文件夹发生了ENTRY_DELETE事件! 46 图片发生了ENTRY_CREATE事件! 47 OS执行过程:新建了一个名为“新建文件夹”的文件夹,再把此文件夹重命名为指定的名称。 48 重命名时,”新建文件夹“消失了,算做删除,”图片“出现了,算做新建。 49 50 六、在图片目录下,随便新建一个文件或者文件夹 51 图片发生了ENTRY_MODIFY事件! 52 说明监控的只是子文件、子文件夹,不会递归监控。 53 54 七、全选,删除test下全部文件、子文件夹 55 图片发生了ENTRY_DELETE事件! 56 1.txt.txt发生了ENTRY_DELETE事件! 57 2.txt发生了ENTRY_DELETE事件! 58 */ 59 60 61 } 62 }
拉取一个WatchKey有3种方法: