Java NIO文件操作--相关类
Buffer类 CharBuffer charBuffer = CharBuffer.allocate(8); charBuffer.capacity(); charBuffer.limit(); charBuffer.position(); 通过allocate()方法创建的Buffer对象是普通Buffer,ByteBuffer还提供了一个allocateDirect()方法类创建直接Buffer。直接Buffer的创建成本比普通Buffer的创建成本高,但直接Buffer的读取效率高! 也就是说直接Buffer适用于长期生存期的Buffer,而不适用于短生存期的Buffer.并且只有ByteBuffer才提供了allocateDirect()方法。 FileChannel类 FileChannel fileChannelIn = fileInputStream.getChannel(); FileChannel fileChannelOut = fileOutputStream.getChannel(); MappedByteBuffer mappedByteBuffer = fileChannelIn.map(MapMode.READ_ONLY, 0, filein.length()); fileChannelOut.write(mappedByteBuffer); 文件锁FileLock fileChannel = new FileOutputStream("a.txt").getChannel(); FileLock fileLock = fileChannel.tryLock(); Thread.sleep(10000);//文件处理 fileLock.release(); 文件锁:可以有效的阻止多个进程并发修改同一个文件。 lock()试图锁定某个文件,如果无法得到文件锁,程序一直阻塞。 tryLock()尝试锁定某个文件,它将直接返回而不是阻塞,如果获得了文件锁,该方法则返回该文件锁,否则返回null。 lock(long postion, long size, boolean shared)对文件从postion开始,长度为size的内容加锁,该方法是阻塞式的。 tryLock(long postion, long size,boolean shared) 非阻塞式的加锁方法,参数同上。 当参数shared为true时,寿命该锁是一个共享锁,他将允许多个进程来读取文件,但阻止其他进程获得对该文件的排他锁。 当参数为false时,表明该锁是一个排他锁,他将锁住对该文件的读写。程序可以调用FileLock的isShared来判断它获得的锁是否是共享锁。 FileVisitor public static void main(String[] args) throws IOException { Files.walkFileTree(Paths.get("D:\\"),new SimpleFileVisitor<Path>(){ @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { System.out.println("正在访问的路径="+dir); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { if (file.endsWith("FileVisitorTest.java")) { System.out.println("找到目标文件"); return FileVisitResult.TERMINATE; } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { return super.visitFileFailed(file, exc); } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { System.out.println("访问结束"); return super.postVisitDirectory(dir, exc); } }); } 如示例,可以使用FileVisitor 进行磁盘文件查找。 WatchService public static void main(String[] args) { try { WatchService watchService = FileSystems.getDefault().newWatchService(); Paths.get("D:\\").register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE,StandardWatchEventKinds.ENTRY_MODIFY); while(true){ WatchKey key = watchService.take(); for (WatchEvent<?> event : key.pollEvents()) { System.out.println(event.context()+ "发生了"+event.kind()+"事件"); } boolean vaild = key.reset();//重设WatchKey if (!vaild) {//如果重设失败,退出监听 break; } } } catch (IOException | InterruptedException e) { e.printStackTrace(); } } 使用的是D盘目录进行监听,这个监控文件变化的监听器可以做到对D盘和它的第一级子目录的变化进行监听,对它的子目录内部的变化无法做到监听。 WatchService有3个方法来获取舰艇目录的文件变化事件。 poll():获取下一个WatchKey,如果没有WatchKey发生就立即返回null。 poll(long timeout, TimeUnit unit):尝试等待timeout时间去获取下一个WatchKey。 take() : 获取下一个WatchKey,如果没有WatchKey发生就移植等待。 如果程序需要一直监控,则选择take()方法。如果程序需要监听指定时间,使用poll()方法。 访问文件属性BasicFileAttributeView public static void main(String[] args) { Path testPath = Paths.get(".\\src\\com\\yin\\nio\\AttributeViewTest.java"); BasicFileAttributeView basicView = Files.getFileAttributeView(testPath, BasicFileAttributeView.class); try { BasicFileAttributes basicFileAttributes = basicView.readAttributes(); PrintStr("创建时间:"+new Date(basicFileAttributes.creationTime().toMillis()).toLocaleString()); PrintStr("最后访问时间:"+new Date(basicFileAttributes.lastAccessTime().toMillis()).toLocaleString()); PrintStr("最后修改时间:"+new Date(basicFileAttributes.lastModifiedTime().toMillis()).toLocaleString()); PrintStr("文件大小:"+basicFileAttributes.size()); } catch (IOException e) { e.printStackTrace(); } } private static void PrintStr(String str){ System.out.println(str); } Java NIO2(AIO) JDK1.7 NIO2主要改进了Classic I/O中java.io.File类对文件操作的局限性 NIO2还带来了真正意义上的Asynchronous I/O(异步I/O),具体实现分为文件Asynchronous I/O与网络传输Asynchronous I/O。因此NIO2也称为AIO。 NIO2 在 File 操作方面的升级 Path介绍:URI,FileSystems Paths、Files工具类介绍 WatchService接口:提供了通过应用程序监听操作系统文件变更事件的能力 文件读写 Asynchronous I/O NIO2通过AsynchronousFileChannel提供了异步读写文件的功能。通过AsynchronousFileChannel异步读写文件有CompletionHandler与Future两种方式。 Java 异步 I/O 网络通信实现 NIO2通过引入AsynchronousSocketChannel与AsynchronousServerSocketChannel实现了异步I/O网络通信模型。