greatjone

BlogJava 联系 聚合 管理
  7 Posts :: 24 Stories :: 3 Comments :: 0 Trackbacks
 

本篇主要介绍的是关于nio在文件读写方面的简单应用,具体底层实现原理,并未深究。

新的输入/输出(NIO)库是在JDK 1.4中引入的。它与原来的I/O库最重要的区别是数据打包和传输的方式的不同,原来的 I/O 的方式处理数据,而 NIO 的方式处理数据。按块处理数据比按(流式的)字节处理数据要快得多。但是面向块的I/O缺少一些面向流的I/O所具有的优雅性和简单性。

示例代码:使用IONIO读取一个文件中的内容

 1import java.io.FileInputStream;
 2import java.io.IOException;
 3import java.nio.ByteBuffer;
 4import java.nio.channels.FileChannel;
 5
 6public class Test {           
 7    /**  
 8     * 使用IO读取指定文件的前1024个字节的内容。  
 9     * @param file 指定文件名称。  
10     * @throws java.io.IOException IO异常。  
11     */
 
12    public static void ioRead(String file) throws IOException{
13        FileInputStream in = new FileInputStream(file);
14        byte[] b = new byte[1024];
15        in.read(b);
16        System.out.println(new String(b));
17        in.close();
18    }

19
20    /**  
21     * 使用NIO读取指定文件的前1024个字节的内容。  
22     * @param file 指定文件名称。  
23     * @throws java.io.IOException IO异常。  
24     */
 
25    public static void nioRead(String file) throws IOException{
26        FileInputStream in = new FileInputStream(file);
27        FileChannel channel = in.getChannel();
28
29        ByteBuffer buffer = ByteBuffer.allocate(1024);
30        channel.read(buffer);
31        byte[] b = buffer.array();
32        System.out.println(new String(b));
33        channel.close();
34    }

35}

从以上示例代码中,我们可以看到对于nio非常重要的两个核心概念:通道与缓冲区。

1)通道
     Channel是对原I/O包中的流的模拟,可以通过它读取和写入数据。拿NIO与原来的I/O做个比较,通道就像是流。
   通道与流的不同之处在于通道是双向的。而流只是在一个方向上移动(一个流必须是InputStream或者OutputStream的子类) 而通道可以用于读、写或者同时用于读写。
     因为它们是双向的,所以通道可以比流更好地反映底层操作系统的真实情况。特别是在UNIX模型中,底层操作系统通道是双向的。

2)缓冲区
       NIO库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的。在写入数据时,它是写入到缓冲区中的。任何时候访问NIO中的数据,您都是将它放到缓冲区中。
   缓冲区实质上是一个数组。通常它是一个字节数组,但是也可以使用其他种类的数组。但是一个缓冲区不仅仅是一个数组。缓冲区提供了对数据的结构化访问,而且还可以跟踪系统的读/写进程。
   最常用的缓冲区类型是ByteBuffer 一个ByteBuffer可以在其底层字节数组上进行get/set操作(即字节的获取和设置)
   ByteBuffer不是NIO中唯一的缓冲区类型。事实上,对于每一种基本Java类型都有一种缓冲区类型:
   ByteBuffer
   CharBuffer
   ShortBuffer

   IntBuffer
   LongBuffer
   FloatBuffer
   DoubleBuffer
   每一个Buffer类都是Buffer接口的一个实例。 

文件的读写

nio读取文件涉及三个步骤:
   (1) FileInputStream获取Channel
   (2) 创建Buffer
   (3) 将数据从Channel读到Buffer 中。

文件的写操作与读操作类似。

下面我以文件的拷贝为例,展示一下nio的读写过程:

 1import java.io.FileInputStream;
 2import java.io.FileNotFoundException;
 3import java.io.FileOutputStream;
 4import java.io.IOException;
 5import java.nio.ByteBuffer;
 6import java.nio.channels.FileChannel;
 7
 8/**
 9 * 将一个文件的所有内容拷贝到另一个文件中。
10 * 
11 * 基本步骤:
12 * 1.得到输入输出通道,创建缓冲区
13 * 2.从源文件中将数据读到这个缓冲区中,然后将缓冲区写入目标文件.此过程需不断循环直到源文件结束
14 * 
15 * @author greatjone
16 */

17public class CopyFile {
18    public static void copy(String file,String copyfile) throws IOException{
19         // 获取源文件和目标文件的输入输出流
20        FileInputStream fin = new FileInputStream(file);
21        FileOutputStream fout = new FileOutputStream(copyfile);
22
23        // 获取输入输出通道
24        FileChannel fcin = fin.getChannel();
25        FileChannel fcout = fout.getChannel();
26
27        // 创建缓冲区
28        ByteBuffer buffer = ByteBuffer.allocate(1024);
29
30        while (true{
31            // clear方法重设缓冲区,使它可以接受读入的数据
32            buffer.clear();
33
34            // 从输入通道中将数据读到缓冲区
35            int r = fcin.read(buffer);
36
37            // read方法返回读取的字节数,可能为零,如果该通道已到达流的末尾,则返回-1
38            if (r == -1{
39                break;
40            }

41            
42            // flip方法让缓冲区可以将新读入的数据写入另一个通道
43            buffer.flip();
44
45            // 从输出通道中将数据写入缓冲区
46            fcout.write(buffer);
47        }

48    }

49}

50

 关于nio更加详细深入研究请参考:http://zhangshixi.javaeye.com/category/101360


  




posted on 2010-06-07 09:47 jone 阅读(5863) 评论(0)  编辑  收藏 所属分类: java

只有注册用户登录后才能发表评论。


网站导航: