Java IO學習總結(四)

1、NIO緩存

      NIO採用內存映射文件的方式來處理輸入輸出流,將文件或者文件的一段區域映射到內存中,這樣就能夠像訪問內存同樣訪問文件,處理速度比傳統的輸入輸出流要快。最主要的兩個核心對象是Channel(通道)和Buffer(緩衝)。app

1)Buffer大數據

     Buffer是一個抽象類,最主要的實現類是ByteBuffer,其餘基本數據類型都有對應的buffer類。經常使用ByteBuffer和CharBuffer;spa

     建立一個Buffer對象,經過static XXBuffer allocate(int capacity)方法,capacity表明容量。code

     Buffer中主要有三個重要的概念,容量(capacity)、界限(limit)和位置(position)對象

     容量:表示緩衝區的最大數據容量,不能夠爲負值,建立後不能夠改變。blog

     界限:表示數據不能夠被讀出或者寫入的緩衝區索引位置。索引

     位置:表示下一個能夠被讀出或者寫入的緩衝區位置索引,當建立一個buffer對象以後,position爲0,從中讀取兩條數據以後,position則爲2,指向buffer中的第三個數據位置。寫入時相似,position自動向後移動位置。ip

     Buffer中兩個重要方法:flip()和clear();執行flip()方法以後,limit移動到position位置,position置爲0,爲輸出數據作好準備,;執行clear()方法以後,limit移動到capacity位置,position位置置爲0,爲寫入數據作好準備。內存

Buffer經常使用操做示例代碼:

public class BufferTest {
    public static void main(String[] args) {
        // 建立Buffer
        CharBuffer buff = CharBuffer.allocate(10);
        
        // 初始化時:position位置爲0,limit位置等於capacity
        System.out.println("緩衝區容量:" + buff.capacity());
        System.out.println("初始化position位置:" + buff.position());
        System.out.println("初始化limit位置:" + buff.limit());
        
        // 向緩衝區中放入三條數據
        buff.put('A');
        buff.put('B');
        buff.put('C');
        // 此時position位置爲3,limit位置等於capacity
        System.out.println("裝載數據時position位置:" + buff.position());
        System.out.println("裝載數據時limit位置:" + buff.limit());
        
        // 裝載數據結束
        buff.flip();
        // 查看此時position位置爲0,limit位置爲3
        System.out.println("裝載數據完成position位置:" + buff.position());
        System.out.println("裝載數據完成limit位置:" + buff.limit());
        
        // 取出數據,只有使用buff.get()方法時,position自動向後移動位置,使用buff.get(X)position位置不變。
        System.out.println("取出第一個數據" + buff.get());
        System.out.println("取出數據position位置:" + buff.position());
        
        // 取出數據完成
        buff.clear();
        // 查看此時position位置爲0,limit位置等於capacity
        System.out.println("取出數據完成position位置:" + buff.position());
        System.out.println("取出數據完成limit位置:" + buff.limit());
    }
}

2)Channel

     Channel相似於傳統的流對象,能夠直接將指定文件的部分或者所有映射成Buffer,程序不能直接訪問Channel,必須經過Buffer交互;全部的Channel都不能經過構造器來直接建立,而是經過傳統的節點InputStream、OutStream的getChannel()的方法返回對於的Channel。

     Channel有三個主要的方法,map()、read()和write(),map()方法用於將Channel中數據映射成ByteBuffer.

示例代碼

public class ChannelTest {
    public static void main(String[] args) {
        try {
            // 建立文件
            File file = new File("d:\\test.txt");
            
            // 建立輸入和輸出Channel
            FileChannel fic = new FileInputStream(file).getChannel();    
            FileChannel foc = new FileOutputStream("d:\\channel.txt").getChannel();
            
            // 將文件內容所有映射爲ByteBuffer
            MappedByteBuffer buffer = fic.map(MapMode.READ_ONLY, 0, file.length());
            // 將buffer中數據之間輸出到FileChannel中
            foc.write(buffer);
            // 初始化緩衝區
            buffer.clear();
            
            // 建立解碼器用於buffer轉換
            Charset charset = Charset.forName("GBK");
            CharsetDecoder cd = charset.newDecoder();
            
            // 將byteBuffer轉換爲charBuffer用於數據輸出展現
            CharBuffer charbuff = cd.decode(buffer);
            System.out.println("數據爲:" + charbuff);
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

另一種讀取方式

public class ChannelTest1 {
    public static void main(String[] args) {
        try {
            File file = new File("d:\\test.txt");
            FileChannel fci = new FileInputStream(file).getChannel();
            
            // 定義buffer
            ByteBuffer buff = ByteBuffer.allocate(256);
            
            while(fci.read(buff) != -1){
                // 鎖定緩存區域,防止讀取null
                buff.flip();
                // 建立解碼器轉換爲charbuffer輸出
                Charset charset = Charset.forName("GBK");
                CharsetDecoder decode = charset.newDecoder();
                System.out.println(decode.decode(buff));
                
                // 數據讀取完以後,初始化緩衝區
                buff.clear();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
相關文章
相關標籤/搜索