java中的NIO和IO到底是什么区别?20个问题告诉你答案【奔跑吧!JAVA】

【摘要】 Q: NIO和标准IO有什么区别?A:标准IO, 基于字节流和字符流进行操作,阻塞IO。NIO基于通道channel和缓冲区Buffer进行操作,支持非阻塞IO,提供选择器§ JavaNIO核心3组件:§ Channels 通道Q: 通道Channel对象能同时做读写操作吗?还是说需要像标准IO那样,需要同时创建input和output对象才能做读写操作?A:通道Channel是双向的, 既…

Q: NIO和标准IO有什么区别?
A:

  • 标准IO, 基于字节流和字符流进行操作,阻塞IO。
  • NIO基于通道channel和缓冲区Buffer进行操作,支持非阻塞IO,提供选择器

§ JavaNIO核心3组件:

§ Channels 通道


Q: 通道Channel对象能同时做读写操作吗?
还是说需要像标准IO那样,需要同时创建input和output对象才能做读写操作?
A:
通道Channel是双向的, 既可以从channel中读数据,也可以写数据。
可以看到既能调用read也能调用write,且需要依赖缓冲区buffer。

 FileChannel fileChannel = FileChannel.open(new File("a.txt").toPath());
    ByteBuffer buf = ByteBuffer.allocate(1024);
     fileChannel.read(buf);
     fileChannel.write(buf);
  • 注意上图上,fileChannel.read(buf)是将a.txt里的数据读到buf, 即a.txt->buf
  • fileChannel.write(buf)是将buf里的数据写入到a.txt中, 即buf->a.txt,不要搞反啦!
  • 通道和缓冲区的关系

Q: 通道支持异步读写吗
A: 支持。

Q: 通道的读写是否必须要依赖缓冲区buffer?
A: 一般都是依赖buffer的。 但也支持2个管道之间的传输,即管道之间直接读写。

String[] arr=new String[]{"a.txt","b.txt"};
FileChannel in=new FileInputStream(arr[0]).getChannel();
FileChannel out =new FileOutputStream(arr[1]).getChannel();
 
// 将a.txt中的数据直接写进b.txt中,相当于文件拷贝
in.transferTo(0, in.size(), out);

常用的几种Channel

  • FileChannel

Java NIO中的FileChannel是一个连接到文件的通道。可以通过文件通道读写文件。
FileChannel无法设置为非阻塞模式,它总是运行在阻塞模式下

创建方式

RandomAccessFile    file = new RandomAccessFile("D:/aa.txt");
FileChannel    fileChannel = file.getChannel();
  • SocketChannel

Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道。
支持非阻塞模式socketChannel.configureBlocking(false)。
可以通过以下2种方式创建SocketChannel:
打开一个SocketChannel并连接到互联网上的某台服务器。
一个新连接到达ServerSocketChannel时,会创建一个SocketChannel

创建方式

SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("192.168.1.100",80));
  • ServerSocketChannel

Java NIO中的 ServerSocketChannel 是一个可以监听新进来的TCP连接的通道, 就像标准IO中的ServerSocket一样。ServerSocketChannel类在 java.nio.channels包中。
SocketChannel和ServerSocketChannel的区别: 前者用于客户端,后者用于服务端
创建方式:

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket.bind(new InetSocketAddress(80));
serverSocketChannel.configureBlocking(false);
while(true){
    SocketChannel socketChannel = serverSocketChannel.accept();
    if(socketChannle != null)
        doSomething...
}

Buffer缓冲区

  • 我们真正要把数据拿到或者要写数据, 实际上都是通过buffer进行操作的。
    文件 <-> buffer <-> 数据
  • buffer是1个即可读也可写的缓冲区,拥有读写2种模式。
  • buffer的capacity属性限定了每个buffer的最大容量,下面的1024就是capacity。

ByteBuffer buf = ByteBuffer.allocate(1024);

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享