Java NIO与IO的差别和比较

发表于:2014-10-21 09:52

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:mfrbuaa    来源:51Testing软件测试网采编

  导读
  J2SE1.4以上版本号中公布了全新的I/O类库。本文将通过一些实例来简介NIO库提供的一些新特性:非堵塞I/O,字符转换,缓冲以及通道。
  一. 介绍NIO
  NIO包(java.nio.*)引入了四个关键的抽象数据类型,它们共同解决传统的I/O类中的一些问题。
  1. Buffer:它是包括数据且用于读写的线形表结构。当中还提供了一个特殊类用于内存映射文件的I/O操作。
  2. Charset:它提供Unicode字符串影射到字节序列以及逆影射的操作。
  3. Channels:包括socket,file和pipe三种管道,它实际上是双向交流的通道。
  4. Selector:它将多元异步I/O操作集中到一个或多个线程中(它能够被看成是Unix中select()函数或Win32中WaitForSingleEvent()函数的面向对象版本号)。
  二. 回想传统
  在介绍NIO之前,有必要了解传统的I/O操作的方式。以网络应用为例,传统方式须要监听一个ServerSocket,接受请求的连接为其提供服务(服务通常包含了处理请求并发送响应)图一是server的生命周期图,当中标有粗黑线条的部分表明会发生I/O堵塞。
  
图一
  能够分析创建server的每一个详细步骤。首先创建ServerSocket
  ServerSocket server=new ServerSocket(10000);
  然后接受新的连接请求
  Socket newConnection=server.accept();
  对于accept方法的调用将造成堵塞,直到ServerSocket接受到一个连接请求为止。一旦连接请求被接受,server能够读客户socket中的请求。
  InputStream in = newConnection.getInputStream();
  InputStreamReader reader = new InputStreamReader(in);
  BufferedReader buffer = new BufferedReader(reader);
  Request request = new Request();
  while(!request.isComplete()) {
  String line = buffer.readLine();
  request.addLine(line);
  }
  这种操作有两个问题,首先BufferedReader类的readLine()方法在其缓冲区未满时会造成线程堵塞,仅仅有一定数据填满了缓冲区或者客户关闭了套接字,方法才会返回。其次,它回产生大量的垃圾,BufferedReader创建了缓冲区来从客户套接字读入数据,可是相同创建了一些字符串存储这些数据。尽管BufferedReader内部提供了StringBuffer处理这一问题,可是全部的String非常快变成了垃圾须要回收。
  相同的问题在发送响应代码中也存在
  Response response = request.generateResponse();
  OutputStream out = newConnection.getOutputStream();
  InputStream in = response.getInputStream();
  int ch;
  while(-1 != (ch = in.read())) {
  out.write(ch);
  }
  newConnection.close();
  类似的,读写操作被堵塞并且向流中一次写入一个字符会造成效率低下,所以应该使用缓冲区,可是一旦使用缓冲,流又会产生很多其它的垃圾。
31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号