athrunwang

          紀(jì)元
          數(shù)據(jù)加載中……
          關(guān)于NIO對(duì)文件讀寫(xiě)的簡(jiǎn)單總結(jié)

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

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

          示例代碼:使用IONIO讀取一個(gè)文件中的內(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個(gè)字節(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個(gè)字節(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}

          從以上示例代碼中,我們可以看到對(duì)于nio非常重要的兩個(gè)核心概念:通道與緩沖區(qū)。

          1)通道
               Channel是對(duì)原I/O包中的流的模擬,可以通過(guò)它讀取和寫(xiě)入數(shù)據(jù)。拿NIO與原來(lái)的I/O做個(gè)比較,通道就像是流。
             通道與流的不同之處在于通道是雙向的。而流只是在一個(gè)方向上移動(dòng)(一個(gè)流必須是InputStream或者OutputStream的子類(lèi)) 而通道可以用于讀、寫(xiě)或者同時(shí)用于讀寫(xiě)。
               因?yàn)樗鼈兪请p向的,所以通道可以比流更好地反映底層操作系統(tǒng)的真實(shí)情況。特別是在UNIX模型中,底層操作系統(tǒng)通道是雙向的。

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

             IntBuffer
             LongBuffer
             FloatBuffer
             DoubleBuffer
             每一個(gè)Buffer類(lèi)都是Buffer接口的一個(gè)實(shí)例。 

          文件的讀寫(xiě)

          nio讀取文件涉及三個(gè)步驟:
             (1) FileInputStream獲取Channel
             (2) 創(chuàng)建Buffer
             (3) 將數(shù)據(jù)從Channel讀到Buffer 中。

          文件的寫(xiě)操作與讀操作類(lèi)似。

          下面我以文件的拷貝為例,展示一下nio的讀寫(xiě)過(guò)程:

           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 * 將一個(gè)文件的所有內(nèi)容拷貝到另一個(gè)文件中。
          10 * 
          11 * 基本步驟:
          12 * 1.得到輸入輸出通道,創(chuàng)建緩沖區(qū)
          13 * 2.從源文件中將數(shù)據(jù)讀到這個(gè)緩沖區(qū)中,然后將緩沖區(qū)寫(xiě)入目標(biāo)文件.此過(guò)程需不斷循環(huán)直到源文件結(jié)束
          14 * 
          15 * @author greatjone
          16 */

          17public class CopyFile {
          18    public static void copy(String file,String copyfile) throws IOException{
          19         // 獲取源文件和目標(biāo)文件的輸入輸出流
          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方法重設(shè)緩沖區(qū),使它可以接受讀入的數(shù)據(jù)
          32            buffer.clear();
          33
          34            // 從輸入通道中將數(shù)據(jù)讀到緩沖區(qū)
          35            int r = fcin.read(buffer);
          36
          37            // read方法返回讀取的字節(jié)數(shù),可能為零,如果該通道已到達(dá)流的末尾,則返回-1
          38            if (r == -1{
          39                break;
          40            }

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

          48    }

          49}

          50

           關(guān)于nio更加詳細(xì)深入研究請(qǐng)參考:http://zhangshixi.javaeye.com/category/101360

          posted on 2012-01-03 17:28 AthrunWang 閱讀(387) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 元朗区| 微山县| 绍兴市| 大安市| 中江县| 崇信县| 中宁县| 新和县| 麟游县| 铜梁县| 韶山市| 临汾市| 武定县| 桦川县| 六盘水市| 炉霍县| 福鼎市| 扎囊县| 伊春市| 合作市| 永州市| 大同市| 西峡县| 昂仁县| 乌拉特后旗| 正定县| 托克托县| 祁门县| 璧山县| 金阳县| 阿克苏市| 游戏| 泽库县| 麻阳| 工布江达县| 通江县| 长垣县| 砀山县| 格尔木市| 宁南县| 抚顺县|