NIO:我认为翻译成Non-Blocking
,更加的通俗直白,相比于BIO,也有一个对比,叫他非阻塞IO最好不过了
双向
的,即可以读又可以写,相比于Stream,它并不区分出输入流和输出流,而且Channel可以完成非阻塞的读写,也可以完成阻塞的读写position
为当前指针位置,limit
用于读模式,用它来标记可读的最大范围,capacity
是最大的可写范围阈值当我们写数据写了四个格子时,我们执行flip()
方法,即可转变为读模式
,limit指针就直接变到了我们刚刚写数据的极限位置,position指针回到初始位置,这样我们就可以将数据读出来了
clear()
方法,它会使position指针回到初始位置,limit回到最远端,这样就可以重新开始数据了,虽然clear意为清除,但是其实它只是将指针的位置移动了,并没有将数据清除,而是会覆盖原来的位置compact()
方法将没有读到的数据保存到初始位置
,而position指针的位置将会移动到这些数据的后面位置
,从未读的数据后开始进行写数据Channel间的数据交换,都需要依赖Buffer
import java.io.*; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; interface FileCopyRunner{ void copyFile(File source,File target); } public class FileCopyDemo { private static void close(Closeable closeable){ if(closeable != null) { try { closeable.close(); } catch (IOException e) { e.printStackTrace(); } } } //不使用任何缓冲的留的拷贝 private static FileCopyRunner noBufferStreamCopy = new FileCopyRunner() { @Override public void copyFile(File source, File target) { InputStream fin = null; OutputStream fout = null; try { fin = new FileInputStream(source); fout = new FileOutputStream(target); int result; while((result = fin.read()) != - 1){ fout.write(result); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { close(fin); close(fout); } } }; //使用缓冲区的流的拷贝 private static FileCopyRunner bufferStreamCopy = new FileCopyRunner() { @Override public void copyFile(File source, File target) { InputStream fin = null; OutputStream fout = null; try { fin = new FileInputStream(source); fout = new FileOutputStream(target); //创建缓冲区 byte[] buffer = new byte[1024]; int result; while((result = fin.read(buffer)) != -1){ //result这里表示从中读出来的具体字节数 //虽然缓冲区中能缓存1024,但是我们读取的时候不一定就有这么多字节 //所以我们使用result做下面的参数 fout.write(buffer,0,result); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { close(fin); close(fout); } } }; //使用带有缓冲区的channel复制 nio private static FileCopyRunner nioBufferCopy = new FileCopyRunner() { @Override public void copyFile(File source, File target) { FileChannel fin = null; FileChannel fout = null; try { fin = new FileInputStream(source).getChannel(); fout = new FileOutputStream(target).getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocate(1024); while(fin.read(byteBuffer) != -1){ byteBuffer.flip();//转变为读模式 while (byteBuffer.hasRemaining()){ fout.write(byteBuffer); } byteBuffer.clear();//转变为写模式 } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { close(fin); close(fout); } } }; //使用没有缓冲区的channel复制文件 private static FileCopyRunner nioTransferCopy = ((source, target) -> { FileChannel fin = null; FileChannel fout = null; try { fin = new FileInputStream(source).getChannel(); fout = new FileOutputStream(target).getChannel(); long transferred = 0L; long size = fin.size(); while(transferred != size){ //如果拷贝的大小没有达到源文件的大小就要一直拷贝 transferred += fin.transferTo(0,size,fout); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { close(fin); close(fout); } }); public static void main(String[] args) { File source = new File("J:\\StudySpace\\Java秒杀系统方案优化-高性能高并发实战\\project.zip"); File target = new File("J:\\StudySpace\\Java秒杀系统方案优化-高性能高并发实战\\p1.zip"); File target2 = new File("J:\\StudySpace\\Java秒杀系统方案优化-高性能高并发实战\\p2.zip"); File target3 = new File("J:\\StudySpace\\Java秒杀系统方案优化-高性能高并发实战\\p3.zip"); File target4 = new File("J:\\StudySpace\\Java秒杀系统方案优化-高性能高并发实战\\p4.zip"); new Thread(() -> noBufferStreamCopy.copyFile(source,target)).start(); new Thread(() -> bufferStreamCopy.copyFile(source,target2)).start(); new Thread(() -> nioBufferCopy.copyFile(source,target3)).start(); new Thread(() -> nioTransferCopy.copyFile(source,target4)).start(); } }
CONNECT
:socketChannel已经与服务器建立连接的状态;ACCEPT
:serverSocketChannel已经与客户端建立连接的状态;READ
:可读状态;WRITE
:可写状态