JAVA-6NIO之FileChannel

Java NIO中的FileChannel是一個鏈接到文件的通道。能夠經過文件通道讀寫文件。緩存

FileChannel沒法設置爲非阻塞模式,它老是運行在阻塞模式下。dom

打開FileChannel

在使用FileChannel以前,必須先打開它。可是,咱們沒法直接打開一個FileChannel,須要經過使用一個InputStream、OutputStream或RandomAccessFile來獲取一個FileChannel實例。性能

 

從FileChannel讀取數據

調用多個read()方法之一從FileChannel中讀取數據。spa

 

首先,分配一個Buffer。從FileChannel中讀取的數據將被讀到Buffer中。操作系統

而後,調用FileChannel.read()方法。該方法將數據從FileChannel讀取到Buffer中。read()方法返回的int值表示了有多少字節被讀到了Buffer中。若是返回-1,表示到了文件末尾。指針

向FileChannel寫數據

使用FileChannel.write()方法向FileChannel寫數據,該方法的參數是一個Buffer。code

 

注意FileChannel.write()是在while循環中調用的。由於沒法保證write()方法一次能向FileChannel寫入多少字節,所以須要重複調用write()方法,直到Buffer中已經沒有還沒有寫入通道的字節。blog

關閉FileChannel

用完FileChannel後必須將其關閉。如:ip

FileChannel的position方法

有時可能須要在FileChannel的某個特定位置進行數據的讀/寫操做。能夠經過調用position()方法獲取FileChannel的當前位置。內存

也能夠經過調用position(long pos)方法設置FileChannel的當前位置。

 

若是將位置設置在文件結束符以後,而後試圖從文件通道中讀取數據,讀方法將返回-1 —— 文件結束標誌。

若是將位置設置在文件結束符以後,而後向通道中寫數據,文件將撐大到當前位置並寫入數據。這可能致使「文件空洞」,磁盤上物理文件中寫入的數據間有空隙。

FileChannel的size方法

FileChannel實例的size()方法將返回該實例所關聯文件的大小。如:

FileChannel的truncate方法

可使用FileChannel.truncate()方法截取一個文件。截取文件時,文件將中指定長度後面的部分將被刪除。如:

這個例子截取文件的前1024個字節。

FileChannel的force方法

FileChannel.force()方法將通道里還沒有寫入磁盤的數據強制寫到磁盤上。出於性能方面的考慮,操做系統會將數據緩存在內存中,因此沒法保證寫入到FileChannel裏的數據必定會即時寫到磁盤上。要保證這一點,須要調用force()方法。

force()方法有一個boolean類型的參數,指明是否同時將文件元數據(權限信息等)寫到磁盤上。

/**
     * file channel
     */
    @Test
    public void text1() throws IOException {
        //從buffer讀
        RandomAccessFile raf = new RandomAccessFile(new File("./test.txt"),"rw");
        FileChannel channel = raf.getChannel();             //獲取通道
        channel.position(channel.size());                   //設置文件末尾位置,做爲寫入初始位置;不帶參獲取指針位置
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);  //緩衝區
        byteBuffer.put("456".getBytes());
        byteBuffer.flip();                                  //反轉
        while (byteBuffer.hasRemaining()) {                 //判斷
            channel.write(byteBuffer);
        }
        channel.truncate(2);                                //截取文件
        channel.force(true);                      //強行寫
        raf.close();
        //向buffer寫
        raf = new RandomAccessFile(new File("./test.txt"),"rw");
        channel = raf.getChannel();
        byteBuffer = ByteBuffer.allocate(1024);
        int read;
        while ((read = channel.read(byteBuffer))!=-1) {
            byteBuffer.flip();                                  //反轉
            while (byteBuffer.hasRemaining()) {                 //判斷
                System.err.print((char)byteBuffer.get());       //輸出
            }
            byteBuffer.clear();                                 //清除
        }
    }
相關文章
相關標籤/搜索