javaNIO使用

来源:互联网 发布:双色球走势图软件 编辑:程序博客网 时间:2024/06/04 18:16

转载自:李会军•宁静致远

最近由于工作关系要做一些Java方面的开发,其中最重要的一块就是Java NIO(New I/O),尽管很早以前了解过一些,但并没有认真去看过它的实现原理,也没有机会在工作中使用,这次也好重新研究一下,顺便写点东西,就当是自己学习 Java NIO的笔记了。本文为NIO使用及原理分析的第一篇,将会介绍NIO中几个重要的概念。

在Java1.4之前的I/O系统中,提供的都是面向流的I/O系统,系统一次一个字节地处理数据,一个输入流产生一个字节的数据,一个输出流消费一个字节的数据,面向流的I/O速度非常慢,而在Java 1.4中推出了NIO,这是一个面向块的I/O系统,系统以块的方式处理处理,每一个操作在一步中产生或者消费一个数据库,按块处理要比按字节处理数据快的多。

在NIO中有几个核心对象需要掌握:缓冲区(Buffer)、通道(Channel)、选择器(Selector)。

缓冲区Buffer

缓冲区实际上是一个容器对象,更直接的说,其实就是一个数组,在NIO库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的; 在写入数据时,它也是写入到缓冲区中的;任何时候访问 NIO 中的数据,都是将它放到缓冲区中。而在面向流I/O系统中,所有数据都是直接写入或者直接将数据读取到Stream对象中。

在NIO中,所有的缓冲区类型都继承于抽象类Buffer,最常用的就是ByteBuffer,对于Java中的基本类型,基本都有一个具体Buffer类型与之相对应,它们之间的继承关系如下图所示:

下面是一个简单的使用IntBuffer的例子:

[java] view plain copy
 print?
  1. import java.nio.IntBuffer;  
  2.   
  3. public class TestIntBuffer {  
  4.     public static void main(String[] args) {  
  5.         // 分配新的int缓冲区,参数为缓冲区容量  
  6.         // 新缓冲区的当前位置将为零,其界限(限制位置)将为其容量。它将具有一个底层实现数组,其数组偏移量将为零。  
  7.         IntBuffer buffer = IntBuffer.allocate(8);  
  8.   
  9.         for (int i = 0; i < buffer.capacity(); ++i) {  
  10.             int j = 2 * (i + 1);  
  11.             // 将给定整数写入此缓冲区的当前位置,当前位置递增  
  12.             buffer.put(j);  
  13.         }  
  14.   
  15.         // 重设此缓冲区,将限制设置为当前位置,然后将当前位置设置为0  
  16.         buffer.flip();  
  17.   
  18.         // 查看在当前位置和限制位置之间是否有元素  
  19.         while (buffer.hasRemaining()) {  
  20.             // 读取此缓冲区当前位置的整数,然后当前位置递增  
  21.             int j = buffer.get();  
  22.             System.out.print(j + "  ");  
  23.         }  
  24.   
  25.     }  
  26.   
  27. }  
运行后可以看到:

在后面我们还会继续分析Buffer对象,以及它的几个重要的属性。

通道Channel

通道是一个对象,通过它可以读取和写入数据,当然了所有数据都通过Buffer对象来处理。我们永远不会将字节直接写入通道中,相反是将数据写入包含一个或者多个字节的缓冲区。同样不会直接从通道中读取字节,而是将数据从通道读入缓冲区,再从缓冲区获取这个字节。

在NIO中,提供了多种通道对象,而所有的通道对象都实现了Channel接口。它们之间的继承关系如下图所示:

使用NIO读取数据

在前面我们说过,任何时候读取数据,都不是直接从通道读取,而是从通道读取到缓冲区。所以使用NIO读取数据可以分为下面三个步骤: 
1. 从FileInputStream获取Channel 
2. 创建Buffer 
3. 将数据从Channel读取到Buffer中

下面是一个简单的使用NIO从文件中读取数据的例子:

[java] view plain copy
 print?
  1. import java.io.*;  
  2. import java.nio.*;  
  3. import java.nio.channels.*;  
  4.   
  5. public class Program {  
  6.     static public void main( String args[] ) throws Exception {  
  7.         FileInputStream fin = new FileInputStream("c:\\test.txt");  
  8.           
  9.         // 获取通道  
  10.         FileChannel fc = fin.getChannel();  
  11.           
  12.         // 创建缓冲区  
  13.         ByteBuffer buffer = ByteBuffer.allocate(1024);  
  14.           
  15.         // 读取数据到缓冲区  
  16.         fc.read(buffer);  
  17.           
  18.         buffer.flip();  
  19.           
  20.         while (buffer.remaining()>0) {  
  21.             byte b = buffer.get();  
  22.             System.out.print(((char)b));  
  23.         }  
  24.           
  25.         fin.close();  
  26.     }  
  27. }  

使用NIO写入数据

使用NIO写入数据与读取数据的过程类似,同样数据不是直接写入通道,而是写入缓冲区,可以分为下面三个步骤: 
1. 从FileInputStream获取Channel 
2. 创建Buffer 
3. 将数据从Channel写入到Buffer中

下面是一个简单的使用NIO向文件中写入数据的例子:

[java] view plain copy
 print?
  1. import java.io.*;  
  2. import java.nio.*;  
  3. import java.nio.channels.*;  
  4.   
  5. public class Program {  
  6.     static private final byte message[] = { 8311110910132,  
  7.         9812111610111546 };  
  8.   
  9.     static public void main( String args[] ) throws Exception {  
  10.         FileOutputStream fout = new FileOutputStream( "c:\\test.txt" );  
  11.           
  12.         FileChannel fc = fout.getChannel();  
  13.           
  14.         ByteBuffer buffer = ByteBuffer.allocate( 1024 );  
  15.           
  16.         for (int i=0; i<message.length; ++i) {  
  17.             buffer.put( message[i] );  
  18.         }  
  19.           
  20.         buffer.flip();  
  21.           
  22.         fc.write( buffer );  
  23.           
  24.         fout.close();  
  25.     }  
  26. }  

本文介绍了Java NIO中三个核心概念中的两个,并且看了两个简单的示例,分别是使用NIO进行数据的读取和写入,Java NIO中最重要的一块Nonblocking I/O将在第三篇中进行分析,下篇将会介绍Buffer内部实现。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小儿三天不大便怎么办 小宝宝腿纹不对怎么办 孩子个子太高怎么办 宝宝拉粑粑干硬怎么办 美国办新生儿护照怎么办 怀孕拉绿色大便怎么办 幼儿园孩子不爱学习怎么办 幼儿园老师管不住孩子怎么办 手机支架夹不住怎么办 画水彩没有留白液怎么办 水彩颜料脱胶了怎么办 指甲油涂到手上怎么办 抖音里没有控雨怎么办 qq视频没有特效怎么办 组长刁难员工员工怎么办 想转行没精力怎么办 桔子树无法退款怎么办 保温箱婴儿哭了怎么办 宝宝不爱吃肉泥怎么办 苹果x卡死了怎么办 苹果6手机用着卡怎么办 二个月宝宝肚子胀气怎么办 一岁半宝宝大便干结怎么办 婴儿上大便费劲怎么办 宝宝便秘半年了怎么办 1岁宝宝便秘怎么办 两个月积食了怎么办 婴儿拉青色大便怎么办 一周岁宝宝便秘怎么办 两岁宝宝内火重怎么办 一岁宝宝内火重怎么办 小孩大便有点血怎么办 一岁半宝宝拉血怎么办 宝宝八个月便秘怎么办 七个月孩子便秘怎么办 小孩肚子胀气怎么办消化不良 骨盆窄孩子卡住怎么办 孕38周便秘怎么办 孕晚期肚子发硬怎么办 小孩脸上有斑怎么办 肚子胀怎么办快速解决