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网络通信模型。