利用JDK7的NIO2.0进行I/O读写和文件操作监控
2014-04-03 21:28
525 查看
最近在学习新的jdk 7提供的NIO 2.0,发现这个东东提供的java.nio.file包里的若干类,大大的方便了文件读写操作,而且编码相当简单,做了很好的封装。它的一个核心类就是Path。
下面就是windows系统下新增,删除,拷贝,move文件的简单示例,注意,需要JDK7的编译和运行环境
另外,在java.nio.file包中还提供了一套监视文件系统变更的WatchService API。可以使用这些API把一个目录注册到监视服务上。在注册的时候需要指定我们感兴趣的事件类型,比如文件创建、文件修改、文件删除等。当监视的事件发生时,监视服务会根据需要处理这些事件。
WatchService是一个接口,在不同的操作系统上有不同的实现,在Windows系统上,具体的实现为 sun.nio.fs.WindowsWatchService,在Linux平台上具体实现为sun.nio.fs.LinuxFileSystem。接着把一个或者若干个监视对象注册到监控服务上,任何实现Watchable接口的对象都可以注册。我们使用实现该接口的Path类来注册监控服务,Path
类实现了接口的register(WatchService, WatchEvent.Kind<?>...) 方法。在注册的时候需要指定想要监视的事件类型,所支持的事件类型如下:
ENTRY_CREATE:创建条目时返回的事件类型
ENTRY_DELETE:删除条目时返回的事件类型
ENTRY_MODIFY:修改条目时返回的事件类型
OVERFLOW:事件丢失或者被丢弃,不必要注册该事件类型
下面是具体的代码示例:
下面就是windows系统下新增,删除,拷贝,move文件的简单示例,注意,需要JDK7的编译和运行环境
import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES; import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.BasicFileAttributes; import java.util.jar.Attributes; public class AIOOperator { /** * 创建文件 * @throws IOException */ public static void createFile() throws IOException { Path target = Paths.get("F:/study-copy.txt"); Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-rw-rw-"); FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perms); Files.createFile(target, attr); } /** * 删除文件 * @throws IOException */ public static void deleteFile() throws IOException { Path target = Paths.get("F:/study-copy.txt"); Files.delete(target); } /** * 拷贝文件 * @throws IOException */ public static void copyFile() throws IOException { Path source = Paths.get("F:/study-copy.txt"); Path target = Paths.get("F:/study-copy2.txt"); Files.copy(source, target, REPLACE_EXISTING); } /** * 移动文件 * @throws IOException */ public static void moveFile() throws IOException { Path source = Paths.get("F:/study-copy.txt"); Path target = Paths.get("d:/study-copy.txt"); Files.move(source, target, REPLACE_EXISTING, COPY_ATTRIBUTES); } public static void main(String[] args) { try { long start = System.currentTimeMillis(); //createFile(); //deleteFile(); //copyFile(); moveFile(); long end = System.currentTimeMillis(); System.out.println("consume -> " + (end - start)); } catch (IOException e) { e.printStackTrace(); } } }
另外,在java.nio.file包中还提供了一套监视文件系统变更的WatchService API。可以使用这些API把一个目录注册到监视服务上。在注册的时候需要指定我们感兴趣的事件类型,比如文件创建、文件修改、文件删除等。当监视的事件发生时,监视服务会根据需要处理这些事件。
WatchService是一个接口,在不同的操作系统上有不同的实现,在Windows系统上,具体的实现为 sun.nio.fs.WindowsWatchService,在Linux平台上具体实现为sun.nio.fs.LinuxFileSystem。接着把一个或者若干个监视对象注册到监控服务上,任何实现Watchable接口的对象都可以注册。我们使用实现该接口的Path类来注册监控服务,Path
类实现了接口的register(WatchService, WatchEvent.Kind<?>...) 方法。在注册的时候需要指定想要监视的事件类型,所支持的事件类型如下:
ENTRY_CREATE:创建条目时返回的事件类型
ENTRY_DELETE:删除条目时返回的事件类型
ENTRY_MODIFY:修改条目时返回的事件类型
OVERFLOW:事件丢失或者被丢弃,不必要注册该事件类型
下面是具体的代码示例:
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE; import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; import static java.nio.file.StandardWatchEventKinds.OVERFLOW; import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import static java.nio.file.LinkOption.NOFOLLOW_LINKS; import java.nio.file.WatchEvent; import java.nio.file.WatchKey; import java.nio.file.WatchService; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class MonitorDir { Map<WatchKey,Path> keys = new ConcurrentHashMap<WatchKey,Path>(); private static WatchService watcher = null; static { try { watcher = FileSystems.getDefault().newWatchService(); } catch (IOException e) { e.printStackTrace(); } } private void register(Path dir) throws IOException { // IOException ,InterruptedException{ WatchKey key = dir.register(watcher, ENTRY_CREATE,ENTRY_DELETE,ENTRY_MODIFY); Path existing = keys.get(key); if (existing == null) { System.out.format("register: %s\n", dir); } else if (!dir.equals(existing)){ System.out.format("update: %s -> %s\n",existing, dir); } keys.put(key, dir); } @SuppressWarnings("unchecked") static <T> WatchEvent<Path> cast(WatchEvent<?> event) { return (WatchEvent<Path>)event; } private void monitor(Path dir) throws IOException,InterruptedException{ register(dir); // 等待监视事件发生 WatchKey key = watcher.take(); // System.out.println(key.getClass().getName()); Path path = keys.get(key); if (path == null) { return; } for (WatchEvent<?> event : key.pollEvents()) { WatchEvent.Kind kind = event.kind(); if (kind == OVERFLOW) { continue; } // 目录监视事件的上下文是文件名 WatchEvent<Path> evt = cast(event); Path name = evt.context(); Path child = path.resolve(name); System.out.format(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + " %s|%s\n", event.kind().name(), child); } // 重置 key boolean valid = key.reset(); if (!valid) { keys.remove(key); if (keys.isEmpty()) { return; } } } public static void main(String[] args) { MonitorDir monitorDir = new MonitorDir(); Path dir = Paths.get("f:/monitortest"); try { monitorDir.monitor(dir); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } }
相关文章推荐
- ubuntu下安装和配置java开发环境
- struts2零配置详解(struts-Convention-plugin)
- JFrame功能简述 java
- java提高篇(二五)-----HashTable
- java数据集合Map接口
- Java Card Development kit (JCDK3)配置及编译
- Java多线程编程
- spring与mybatis整合(基于配置文件)
- JAVA中string.repalce()和string.replaceAll()有什么区别?
- 第三次作业——顺序查找,二分查找
- String类substring方法导致的Java内存泄漏问题
- Java内存溢出的详细解决方案
- java内存管理之二
- java内存管理之一
- java动态数组、集合类、以及数组辅助工具的简单使用
- eclipse编辑器,怎么创建PHP和JAVA的工程项目?
- java中的堆栈
- Java序列化问题
- JAVA编程思想学习第一篇の对象导论
- java23种设计模式的有趣解释