12、NIO、AIO、BIO二
一、NIO2快速读写文件
写完之后记得flush一下,NIO2不能自行创建文件,需要在文件中判断一下。
package com.zxc.L; import org.junit.Test; import java.io.BufferedWriter; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.List; /** * Created by Administrator on 2018/2/6 0006. */ public class E { @Test public void writeFile(){ Path path1= Paths.get("src/com/zxc/L/456.txt"); try { if(!Files.exists(path1)){ Files.createFile(path1); } BufferedWriter bw=Files.newBufferedWriter(path1,StandardCharsets.UTF_8, StandardOpenOption.WRITE); bw.write("我是谁"); bw.flush(); } catch (IOException e) { e.printStackTrace(); } } @Test public void readFile(){ Path path1= Paths.get("src/com/zxc/L/456.txt"); try { List <String>list=Files.readAllLines(path1, StandardCharsets.UTF_8); for(String s:list){ System.out.println(s); } } catch (IOException e) { e.printStackTrace(); } } }
二、监听器
记得重置监听器
import java.io.IOException; import java.nio.file.*; /** * Created by Administrator on 2018/2/6 0006. */ public class F { public static void main(String[] args) { try { WatchService ws= FileSystems.getDefault().newWatchService(); Path path=FileSystems.getDefault().getPath("D://"); WatchKey key=path.register(ws,StandardWatchEventKinds.ENTRY_MODIFY); boolean shutdown=true; while(shutdown){ try { key = ws.take(); for(WatchEvent<?> e:key.pollEvents()){ if (e.kind()==StandardWatchEventKinds.ENTRY_MODIFY){ System.out.println("修改了"); } } } catch (InterruptedException e) { e.printStackTrace(); } key.reset(); shutdown=false; } } catch (IOException e) { e.printStackTrace(); } } }
三、通道读写
package com.zxc.L; import org.junit.Test; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; /** * Created by Administrator on 2018/2/6 0006. */ public class G { public static void main(String[] args) { write(); } private static void write() { Path path1= Paths.get("d://456.txt"); try { FileChannel fc= FileChannel.open(path1, StandardOpenOption.WRITE); fc.write(ByteBuffer.wrap("sad".getBytes())); fc.close(); } catch (IOException e) { e.printStackTrace(); } } @Test public void read(){ Path path1= Paths.get("d://456.txt"); ByteBuffer buffer=ByteBuffer.allocate(1024); try { FileChannel fc= FileChannel.open(path1, StandardOpenOption.READ); fc.read(buffer,1); buffer.flip();//使指针返回到缓冲区第一个位置,在读取之前调用。 Charset c=Charset.forName("UTF-8"); System.out.println(c.decode(buffer)); fc.close(); } catch (IOException e) { e.printStackTrace(); } } }
四、异步IO读写基础
NIO2的异步能力使用于套接字和文件IO操作,其实异步IO只是一种在读写操作结束前允许进行其他操作的IO处理
java7中有三个新的异步通道:
AsynchronousFileChannel -用于文件IO
AsynchronousSocketChannel -用于套接字IO,支持超时
AsynchronousServerSocketChannel -用于套接字接受异步连接
使用异步API,主要形式:将来式、回调式
将来式:使用java.util.concurrent.Future接口
使用场合:当你希望由主控线程发起IO操作并轮询等到结果时使用将来式异步处理。
1、打开一个AsynchronousFileChannel来读写文件
2、采用了AsynchronousFileChannel,并用Future保存读取结果,所以会自动采用并发IO处理
3、在读取数据时,主线程可以继续执行其他任务。
4、当任务读取完成时,检查数据读取结果。
package com.weikun.A; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousFileChannel; import java.nio.file.Path; import java.nio.file.Paths; import java.util.concurrent.Future; public class H { public static void main(String[] args) { // TODO Auto-generated method stub try { //1异步打开文件 Path file=Paths.get("g://video//0528///流1.wmv");//找一个比较大的文件 AsynchronousFileChannel channel=AsynchronousFileChannel.open(file); //2读取1000000字节 ByteBuffer buffer=ByteBuffer.allocate(1024*10); Future<Integer> result=channel.read(buffer, 0); while(!result.isDone()){//3可以干点别的事情 System.out.println("卫老师");//主线程可以打印些别的 } Integer bytesRead=result.get(); System.out.println("read:["+bytesRead+"]"); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } }
回调式:匿名内部类中可以分块处理io操作时遇到的情况,并不是向将来式一样可以在io同时主线程做其他的事
import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousFileChannel; import java.nio.channels.CompletionHandler; import java.nio.file.Path; import java.nio.file.Paths; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; public class J { public static void main(String[] args) throws IOException, InterruptedException, ExecutionException { Path filePath = Paths.get("1.sql"); AsynchronousFileChannel afc = AsynchronousFileChannel.open(filePath); ByteBuffer byteBuffer = ByteBuffer.allocate(16 * 1024); //??个数有关 //使用FutureDemo时,请注释掉completionHandlerDemo,反之亦然 //futureDemo(afc, byteBuffer); afc.read(byteBuffer, 0, null, new CompletionHandler<Integer, Object>() { @Override public void completed(Integer result, Object attachment) { System.out.println("Bytes Read = " + result); } @Override public void failed(Throwable exc, Object attachment) { System.out.println(exc.getCause()); } }); System.out.println("Waiting for completion..."); System.out.println("End"); afc.close(); }