为啥要使用NIO?

NIO的创建目的是为了让JAVA程序员可以实现高速I/O而无需编写自定义的本机代码。NIO将最耗时的I/O操作(即填充和提取缓冲区)转移回操作系统,因而可以极大地提高速度

流与快的比较

原来的I/O库(在java.io.*中)与NIO最重要的区别是数据打包和传输的方式,原来的I/O以流的方式处理数据,而NIO以快的方式处理数据。

面向流的I/O系统一次一个字节地处理数据。一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。不利的一面是,面向流的I/O通常相当慢。

一个面向快的I/O系统以快的形式处理数据。每一个操作都在一步中产生或消费一个数据块。按快处理数据比按(流式的)字节处理数据要快的多,但是面向快的I/O缺少一些面向流的I/O所具有的优雅性和简单性。

缓冲区

在NIO库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读取到缓冲区中的,在写入数据时,它是写入到缓冲区中的。任何时候访问NIO中的数据,都是将它放到缓冲区中

缓冲区实质上一个数组。通常它是一个字节数组,但是也可以使用其他种类的数组。但是一个缓冲区不仅仅是一个数组。缓冲区提供了对数据的结构化访问,而且还可以跟踪系统的读/写进程。

缓冲区类型

最常用的缓冲区类型是ByteBuffer。一个ByteBuffer可以在其底层字节数组上进行get/set操作(即字节的获取和设置)。ByteBuffer不是NIO中唯一的缓冲区类型。事实上,对于每一种基本java类型都有一种缓冲区类型:

ByteBuffer   CharBuffer  ShortBuffer  IntBuffer  LongBuffer  FloatBuffer  DoubleBuffer

缓冲区内部细节:

状态变量

可以用三个值指定缓冲区在任意时刻的状态:

position                             limit         capacity

public class NIIODemo {

    /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("----------");
ByteBuffer buf=ByteBuffer.allocate(10);
System.out.println("position="+buf.position());
System.out.println("limit="+buf.limit());
System.out.println("capacity="+buf.capacity());
System.out.println("----------");
buf.put((byte) 10);
byte[] bs={20,30,40};
buf.put(bs);
ByteBuffer buf1=ByteBuffer.allocate(10);
System.out.println("position="+buf.position());
System.out.println("limit="+buf.limit());
System.out.println("capacity="+buf.capacity());
System.out.println("----------");
buf.flip();//反转,将position回到初始位置,limit等于position的值
ByteBuffer buf2=ByteBuffer.allocate(10);
System.out.println("position="+buf.position());
System.out.println("limit="+buf.limit());
System.out.println("capacity="+buf.capacity());
System.out.println("----------"); //取值
//返回当前位置与限制之间的元素
for(int i=0;i<buf.remaining();i++){
System.out.println(buf.get(i));
}
} }

通道:Channel

Channel是一个对象,可以通过它读取和写入数据。拿NIO与原来的I/O做个比较,通道就像是流。

正如前面提到的,所有数据都通过Buffer对象来处理。永远不会将字节直接写入通道中,相反,您是将数据写入包含一个或者多个字节的缓冲区。同样,您不会直接从通道中读取字节,而是将数据从通道读入缓冲区,再从缓冲区获取这个字节。

/**
* 文件的读写操作:1.内存映射方式(最快) 2.NIO的文件通道读写(第二块) 3.传统的IO读写(最慢)
* @author Administrator
*
*/
public class FileCopyDemo { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//copy(new File("c:\\aaa.txt"),new File("c:\\aaa\\aaa.txt"));
RandomAccessFileDemo();
} public static void copy(File src,File dest){
try {
FileInputStream in=new FileInputStream(src);
FileOutputStream out=new FileOutputStream(dest);
FileChannel fcin=in.getChannel();//获取文件通道
FileChannel fcout=out.getChannel(); ByteBuffer buf=ByteBuffer.allocate((int)src.length());
fcin.read(buf);
buf.flip();
fcout.write(buf); fcin.close();
fcout.close();
in.close();
out.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } public static void RandomAccessFileDemo(){
try {
RandomAccessFile in=new RandomAccessFile(new File("c:\\aaa.txt"),"r");
RandomAccessFile out=new RandomAccessFile(new File("c:\\aaa\\aaa.txt"),"rw"); FileChannel inChannel=in.getChannel();
FileChannel outChannel=out.getChannel();
long size=inChannel.size();
//映射内存
MappedByteBuffer inbuf=inChannel.map(MapMode.READ_ONLY, 0, size);
MappedByteBuffer outbuf=outChannel.map(MapMode.READ_WRITE, 0, size);
//buf.flip();
for(int i=0;i<size;i++){
byte b=inbuf.get(i);
outbuf.put(i,b);
} inChannel.close();
outChannel.close();
in.close();
out.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }

最新文章

  1. angularjs和ajax的结合使用 (二)
  2. 网页游戏外挂辅助AMF模拟通讯必备
  3. 【转】HTTP 头部解释,HTTP 头部详细分析,最全HTTP头部信息
  4. Beaglebone Black &ndash; 连接 GY-91 MPU9250+BMP280 九轴传感器(2)
  5. iOS开发-微博客户端-基本界面搭建(01)
  6. HTTP 错误 405.0 - Method Not Allowed
  7. asp.net,mvc4,mysql数据库,Ef遇到问题集合
  8. ubuntu下QT输出程序控制台界面难看的解决方法
  9. 利用Ring Buffer在SQL Server 2008中进行连接故障排除
  10. Tomcat(.jsp)
  11. nuxtjs中修改head及vuex的使用
  12. centos7 安装 nvm
  13. Beta 冲刺 (7/7)
  14. 如何在Ubuntu 18.04上安装和配置Apache 2 Web服务器(转)
  15. MapReduce教程(一)基于MapReduce框架开发&lt;转&gt;
  16. Parallel.For with await and wait()
  17. linux设置端口转发(一键设置)
  18. 退出循环break,在while、for、do...while、循环中使用break语句退出当前循环,直接执行后面的代码。
  19. django的forms
  20. FTP 搭建

热门文章

  1. HDOJ2553(2N皇后问题)
  2. 完美前向保密PFS
  3. rufus-scheduler定时任务示例代码
  4. springMVC绑定json参数之二(2.2.2)
  5. source in sight 删除工程
  6. WEB服务器(IIS)的配置与管理
  7. 线程中event.wait() event_obj.set() 的使用
  8. netstat查看网络信息
  9. 【总结整理】JQuery基础学习---样式篇
  10. 9、samtool view