greatjone

          BlogJava 聯(lián)系 聚合 管理
            7 Posts :: 24 Stories :: 3 Comments :: 0 Trackbacks
           

          本篇主要介紹的是關于nio在文件讀寫方面的簡單應用,具體底層實現(xiàn)原理,并未深究。

          新的輸入/輸出(NIO)庫是在JDK 1.4中引入的。它與原來的I/O庫最重要的區(qū)別是數(shù)據(jù)打包和傳輸?shù)姆绞降牟煌瓉淼?/span> I/O 的方式處理數(shù)據(jù),而 NIO 的方式處理數(shù)據(jù)。按塊處理數(shù)據(jù)比按(流式的)字節(jié)處理數(shù)據(jù)要快得多。但是面向塊的I/O缺少一些面向流的I/O所具有的優(yōu)雅性和簡單性。

          示例代碼:使用IONIO讀取一個文件中的內(nèi)容

           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個字節(jié)的內(nèi)容。  
           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個字節(jié)的內(nèi)容。  
          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非常重要的兩個核心概念:通道與緩沖區(qū)。

          1)通道
               Channel是對原I/O包中的流的模擬,可以通過它讀取和寫入數(shù)據(jù)。拿NIO與原來的I/O做個比較,通道就像是流。
             通道與流的不同之處在于通道是雙向的。而流只是在一個方向上移動(一個流必須是InputStream或者OutputStream的子類) 而通道可以用于讀、寫或者同時用于讀寫。
               因為它們是雙向的,所以通道可以比流更好地反映底層操作系統(tǒng)的真實情況。特別是在UNIX模型中,底層操作系統(tǒng)通道是雙向的。

          2)緩沖區(qū)
                 NIO庫中,所有數(shù)據(jù)都是用緩沖區(qū)處理的。在讀取數(shù)據(jù)時,它是直接讀到緩沖區(qū)中的。在寫入數(shù)據(jù)時,它是寫入到緩沖區(qū)中的。任何時候訪問NIO中的數(shù)據(jù),您都是將它放到緩沖區(qū)中。
             緩沖區(qū)實質(zhì)上是一個數(shù)組。通常它是一個字節(jié)數(shù)組,但是也可以使用其他種類的數(shù)組。但是一個緩沖區(qū)不僅僅是一個數(shù)組。緩沖區(qū)提供了對數(shù)據(jù)的結(jié)構化訪問,而且還可以跟蹤系統(tǒng)的讀/寫進程。
             最常用的緩沖區(qū)類型是ByteBuffer 一個ByteBuffer可以在其底層字節(jié)數(shù)組上進行get/set操作(即字節(jié)的獲取和設置)
             ByteBuffer不是NIO中唯一的緩沖區(qū)類型。事實上,對于每一種基本Java類型都有一種緩沖區(qū)類型:
             ByteBuffer
             CharBuffer
             ShortBuffer

             IntBuffer
             LongBuffer
             FloatBuffer
             DoubleBuffer
             每一個Buffer類都是Buffer接口的一個實例。 

          文件的讀寫

          nio讀取文件涉及三個步驟:
             (1) FileInputStream獲取Channel
             (2) 創(chuàng)建Buffer
             (3) 將數(shù)據(jù)從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 * 將一個文件的所有內(nèi)容拷貝到另一個文件中。
          10 * 
          11 * 基本步驟:
          12 * 1.得到輸入輸出通道,創(chuàng)建緩沖區(qū)
          13 * 2.從源文件中將數(shù)據(jù)讀到這個緩沖區(qū)中,然后將緩沖區(qū)寫入目標文件.此過程需不斷循環(huán)直到源文件結(jié)束
          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        // 創(chuàng)建緩沖區(qū)
          28        ByteBuffer buffer = ByteBuffer.allocate(1024);
          29
          30        while (true{
          31            // clear方法重設緩沖區(qū),使它可以接受讀入的數(shù)據(jù)
          32            buffer.clear();
          33
          34            // 從輸入通道中將數(shù)據(jù)讀到緩沖區(qū)
          35            int r = fcin.read(buffer);
          36
          37            // read方法返回讀取的字節(jié)數(shù),可能為零,如果該通道已到達流的末尾,則返回-1
          38            if (r == -1{
          39                break;
          40            }

          41            
          42            // flip方法讓緩沖區(qū)可以將新讀入的數(shù)據(jù)寫入另一個通道
          43            buffer.flip();
          44
          45            // 從輸出通道中將數(shù)據(jù)寫入緩沖區(qū)
          46            fcout.write(buffer);
          47        }

          48    }

          49}

          50

           關于nio更加詳細深入研究請參考:http://zhangshixi.javaeye.com/category/101360


            




          posted on 2010-06-07 09:47 jone 閱讀(5874) 評論(0)  編輯  收藏 所屬分類: java
          主站蜘蛛池模板: 盐津县| 达日县| 资阳市| 河北省| 张家港市| 迁安市| 民乐县| 青阳县| 富民县| 德惠市| 邵阳县| 衡水市| 确山县| 丹巴县| 大埔县| 龙川县| 获嘉县| 卢湾区| 闵行区| 泾川县| 竹山县| 大悟县| 保定市| 洛川县| 荥经县| 新兴县| 正蓝旗| 聂荣县| 上虞市| 巍山| 剑川县| 闵行区| 平塘县| 和林格尔县| 富源县| 裕民县| 霍林郭勒市| 石家庄市| 茌平县| 鄄城县| 福建省|