<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 41,  comments - 8,  trackbacks - 0
    java nio的全稱是java new I/O,即一個(gè)全新的I/O控制系統(tǒng),它的API的包名為java.nio,是在jdk1.4后引入的。
    nio之所以為為新,在于它并沒在原來I/O的基礎(chǔ)上進(jìn)行開發(fā),而是提供了全新的類和接口,除了原來的基本功能之外,它還提供了以下新的特征:
            ? 多路選擇的非封鎖式I/O設(shè)施
            ?支持文件鎖和內(nèi)存映射
            ?支持基于Perl風(fēng)格正則表達(dá)式的模式匹配設(shè)施
            ?字符集編碼器和譯碼器
            為了支持這些新的功能,nio使用了兩個(gè)新的概念:
              1. 信道(channel)
                  信道是一個(gè)連接,可用于接收或發(fā)送數(shù)據(jù),如文件和套接字。因?yàn)樾诺肋B接的是底層的物理設(shè)備,他可以直接支持設(shè)備的讀/寫,或提供文件鎖。對(duì)于文件、管道、套接字都存在相應(yīng)的信道類。可以把信道看成是數(shù)據(jù)流的替代品。信道沒有包裝類,提高了性能。
                 所有的信道類都位于java.nio.channels包中。
             2. 緩沖區(qū)(buffer)
                  緩沖區(qū)是一個(gè)數(shù)據(jù)容器。可以把它看做內(nèi)存中的一個(gè)大的數(shù)組,用來存儲(chǔ)來自信道的同一類型的所有數(shù)據(jù),因此,程序員可以使用字節(jié)、字符、整數(shù)等緩沖區(qū)。字節(jié)緩沖區(qū)提供必要的方法,可以提取或存入所有基本類型(boolean型除外)的數(shù)據(jù)。 
                  buffer類的核心是一塊內(nèi)存區(qū),便于核心代碼和java代碼同時(shí)訪問,核心代碼可以直接訪問它,java代碼可以通過API訪問它。
                 緩沖區(qū)基本上是一塊內(nèi)存區(qū)域,因而可以執(zhí)行一些與內(nèi)存有關(guān)的操作,如清除其中的內(nèi)容,支持讀寫或只讀操作等。
                 所有的buffer類都位于java.nio包中。
           下面看如何使用它們:
    1.      使用信道
    在信道的使用中,文件的信道是最具有代表性的,API也是最多的,下面我們以文件信道為例介紹它。
         獲取文件信道
    文件的信道的類為FileChannel,遺憾的是他并沒有向我們提供打開文件的方法,我們可以通過調(diào)用FileInputStream、FileOutputStream和RandomAccessFile類實(shí)例的getChannel()方法來獲取其實(shí)例。例如:
    RandomAccessFile raf = new RandomAccessFile(“data.txt”, “rw”);
    FileChannel fc = raf.getChannel();
    請(qǐng)注意,這里打開文件的方式如”rw”將適用于文件信道,FileInputStream實(shí)例的getChannel()方法所獲得的通道將允許進(jìn)行讀取操作。通過FileOutputStream的getChannel方法所獲得的通道將允許進(jìn)行寫入操作。最后,如果使用模式 "r" 創(chuàng)建 RandomAccessFil的實(shí)例,則通過該實(shí)例的getChannel()方法所獲得的通道將允許進(jìn)行讀取操作,如果使用模式 "rw" 創(chuàng)建實(shí)例,則獲得的通道將允許進(jìn)行讀取和寫入操作。
        從信道讀取數(shù)據(jù)
    讀取的數(shù)據(jù)會(huì)默認(rèn)放到字節(jié)緩沖區(qū)中。
    FileChannel提供了四個(gè)API讀取數(shù)據(jù):
    a.    read(ByteBuffer dst) 將字節(jié)序列從此通道讀入給定的緩沖區(qū)
    b.   read(ByteBuffer[] dsts) 將字節(jié)序列從此通道讀入給定的緩沖區(qū)
    c.    read(ByteBuffer[] dsts, int offset, int length)
              將字節(jié)序列從此通道讀入給定緩沖區(qū)的子序列中
    d.    read(ByteBuffer dst, long position)
              從給定的文件位置開始,從此通道讀取字節(jié)序列,并寫入給定的緩沖區(qū)
        向信道寫入數(shù)據(jù)
    數(shù)據(jù)來源默認(rèn)是字節(jié)緩沖區(qū)。
    FileChannel提供了四個(gè)API寫入數(shù)據(jù):
    a. write(ByteBuffer src)
              將字節(jié)序列從給定的緩沖區(qū)寫入此通道
    b. write(ByteBuffer[] srcs)
              將字節(jié)序列從給定的緩沖區(qū)寫入此通道
    c. write(ByteBuffer[] srcs, int offset, int length)
              將字節(jié)序列從給定緩沖區(qū)的子序列寫入此通道
    d. write(ByteBuffer src, long position)
              從給定的文件位置開始,將字節(jié)序列從給定緩沖區(qū)寫入此通道
                ● 使用文件鎖
                   文件鎖機(jī)制主要是在多線程同時(shí)讀寫某個(gè)文件資源時(shí)使用。
                   FileChannel提供了兩種加鎖機(jī)制,lock和tryLock,兩者的區(qū)別在于,lock是同步的,
                   直至成功才返回,tryLock是異步的,無論成不成功都會(huì)立即返回。
                ● 使用內(nèi)存映射
                     FileChannel提供的的API為:
                     MappedByteBuffer map(FileChannel.MapMode mode,  long position, long size);
                          映射模式一個(gè)有三種:
                          a.只讀: 試圖修改得到的緩沖區(qū)將導(dǎo)致拋出 ReadOnlyBufferException.(MapMode.READ_ONLY)
              b.讀/寫 對(duì)得到的緩沖區(qū)的更改最終將傳播到文件;該更改對(duì)映射到同一文件的其他程序不一定是可見的。 (MapMode.READ_WRITE)
                          c.專用 對(duì)得到的緩沖區(qū)的更改不會(huì)傳播到文件,并且該更改對(duì)映射到同一文件的其他程序也不是可見的;相反,會(huì)創(chuàng)建緩沖區(qū)已修改部分的專用副本。 (MapMode.PRIVATE)
    2.      使用緩沖區(qū)
         層次結(jié)構(gòu)
    所有緩沖區(qū)的基類都是Buffer,Boolean類型外,其它數(shù)據(jù)類型都有對(duì)應(yīng)的緩沖區(qū)類,
    另有一個(gè)ByteOrder類,用來設(shè)置緩沖區(qū)的大小端順序,即BigEndian或者是LittleEndian
    默認(rèn)情況下是BigEndian。其層次結(jié)構(gòu)圖如下:
         獲取緩沖區(qū)對(duì)象
    一共有兩種類型的緩沖區(qū),直接緩沖區(qū)和非直接緩沖區(qū),兩者區(qū)別在于直接緩沖區(qū)上的數(shù)據(jù)操作,
    虛擬機(jī)將盡量使用本機(jī)I/O,并盡量避免使用中間緩沖區(qū)。判斷一個(gè)緩沖區(qū)是否是直接緩沖區(qū),
    可以調(diào)用isDirect()方法。
    有三種方式來獲取一個(gè)緩沖區(qū)的對(duì)象:
    a.      調(diào)用allocate()或者allocateDirect()方法直接分配,其中allocateDirect()
    返回的是直接緩沖區(qū)。
    b.      包裝一個(gè)數(shù)組,如:
    byte[] b = new byte[1024];
    ByteBuffer bb = ByteBuffer.wrap(b);
    c.       內(nèi)存映射,即調(diào)用FileChannelmap()方法。
         緩沖區(qū)基本屬性
    這幾個(gè)屬性是每個(gè)緩沖區(qū)都有的并且是常用的操作。
    a.     容量(capacity),緩沖區(qū)大小
    b.      限制(limit),第一個(gè)不應(yīng)被讀取或?qū)懭氲淖止?jié)的索引,總是小于容量。
    c.       位置(position),下一個(gè)被讀取或?qū)懭氲淖止?jié)的索引,總是小于限制。
    d.      clear()方法:設(shè)置limit為capacity,position為0。
    e.      filp()方法:設(shè)置limit為當(dāng)前position,然后設(shè)置position為0。
    f.        rewind()方法:保持limit不變,設(shè)置position為0。
         緩沖區(qū)數(shù)據(jù)操作
    操作包括了讀取和寫入數(shù)據(jù)兩種。
    讀取數(shù)據(jù)使用get()及其系列方法,除boolean外,每一種類型包括了對(duì)應(yīng)的get()方法,
    如getInt(),getChar()等,get()方法用來讀取字節(jié),支持相對(duì)和絕對(duì)索引兩種方式。
    寫入數(shù)據(jù)使用put()及其系列方法,和get()方法是對(duì)應(yīng)的。
               下面這個(gè)例子演示了如何使用緩沖區(qū)和信道:
    
    
    package nio;

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;

    public class BufferDemo {

        
        
    public static void main(String[] args) throws Exception{
            
    //分配一個(gè)非直接緩沖區(qū)
            ByteBuffer bb = ByteBuffer.allocate(100);
            
    //向緩沖區(qū)寫入0到100的字節(jié)制
            for(int i = 0; i <100; i++){
                
    byte b = (byte) (Math.random() * 100);
                bb.put(b);
            }

            
            System.out.println(
    "寫入文件前的緩沖區(qū)數(shù)據(jù)");
            bb.flip();
            
    while(bb.hasRemaining())
                System.out.print(bb.get() 
    + " ");
            System.out.println();
            
            
    //獲取一個(gè)關(guān)聯(lián)到文件buffer.txt的信道
            FileChannel fc = new FileOutputStream("buffer.txt").getChannel();
            
    //將緩沖區(qū)數(shù)據(jù)寫到文件中
            bb.flip();
            fc.write(bb);
            
    //防止緩存
            fc.force(true);
            
    //關(guān)閉信道
            fc.close();
            bb 
    = null;
            fc 
    = null;
            
            
    //下面從文件中讀取數(shù)據(jù)
            fc = new FileInputStream("buffer.txt").getChannel();
            ByteBuffer bb2 
    = ByteBuffer.allocate((int) fc.size());
            fc.read(bb2);
            System.out.println(
    "從文件讀取的緩沖區(qū)數(shù)據(jù)");
            bb2.flip();
            
    while(bb2.hasRemaining())
                System.out.print(bb2.get() 
    + " ");
            System.out.println();
            fc.close();
            bb2 
    = null;
            fc 
    = null;
            

        }


    }

             3.視圖緩沖區(qū)
             上面我們的緩沖區(qū)都是基于字節(jié)的,像IntBuffer、LongBuffer等這些都可以調(diào)用ByteBuffer的
             as***Buffer(***表示某個(gè)數(shù)據(jù)類型)得到,所以這種類型的緩沖區(qū)又被稱為視圖緩沖區(qū)(View Buffer),
           視圖緩沖區(qū)有以下特點(diǎn):
    a.     視圖緩沖區(qū)有自己獨(dú)立的position和limit,但它不是一個(gè)新的創(chuàng)建,只是原來字節(jié)緩沖區(qū)的一個(gè)邏輯緩沖區(qū),字節(jié)緩沖區(qū)的任何修改都會(huì)影響視圖緩沖區(qū),反之亦然。
    b.      視圖緩沖區(qū)按照數(shù)據(jù)類型的大小進(jìn)行索引,而不是字節(jié)順序。
    c.       也提供了put()和get()及其系列方法,用于數(shù)據(jù)的整塊傳輸。
           下面這個(gè)例子演示了視圖緩沖區(qū):
    
    
    package nio;

    import java.io.FileInputStream;
    import java.nio.ByteBuffer;
    import java.nio.IntBuffer;
    import java.nio.channels.FileChannel;

    public class ViewBufferDemo {

        
    public static void main(String[] args) throws Exception{
            
            
    //將文件內(nèi)容讀到緩沖區(qū)中
            FileChannel fc = new FileInputStream("buffer.txt").getChannel();
            ByteBuffer bb 
    = ByteBuffer.allocate((int) fc.size());
            fc.read(bb);
            fc.close();
            fc 
    = null;
            
            System.out.println(
    "從文件讀取的字節(jié)緩沖區(qū)數(shù)據(jù)");
            bb.flip();
            
    while(bb.hasRemaining())
                System.out.print(bb.get() 
    + " ");
            System.out.println();
            
            
    //獲取視圖緩沖區(qū)
            bb.flip();
            IntBuffer ib 
    = bb.asIntBuffer();
            System.out.println(
    "將字節(jié)緩沖區(qū)作為整形緩沖區(qū)的數(shù)據(jù)");
            
    while(ib.hasRemaining())
                System.out.print(ib.get() 
    + " ");
            System.out.println();
            
            bb 
    = null;
            ib 
    = null;
            
        }


    }

           4.映射內(nèi)存緩沖區(qū)
             調(diào)用信道的map()方法后,即可將文件的某一部分或全部映射到內(nèi)存中,映射內(nèi)存緩沖區(qū)是一
             個(gè)直接緩沖區(qū),繼承自ByteBuffer,但相對(duì)于ByteBuffer,它有更多的優(yōu)點(diǎn):
    a.     內(nèi)存映射I/O是對(duì)信道/緩沖區(qū)技術(shù)的改進(jìn)。 當(dāng)傳輸大量的數(shù)據(jù)時(shí),內(nèi)存映射I/O
    速度相對(duì)較快,這是因?yàn)樗褂锰摂M內(nèi)存把文件傳輸?shù)竭M(jìn)程的地址空間中。
    b.      映射內(nèi)存也成為共享內(nèi)存,因此可以用于相關(guān)進(jìn)程(均映射同一文件)之間的整塊數(shù)據(jù)
    傳輸,這些進(jìn)程甚至可以不必位于同一系統(tǒng)上,只要每個(gè)都可以訪問同一文件即可。
    c.       當(dāng)對(duì)FileChannel執(zhí)行映射操作,把文件映射到內(nèi)存中時(shí),得到的是一個(gè)連接到文件的
    映射的字節(jié)緩沖區(qū),這種映射的結(jié)果是,當(dāng)輸出緩沖區(qū)的內(nèi)容時(shí),數(shù)據(jù)將出現(xiàn)在文件中,
    當(dāng)讀入緩沖區(qū)時(shí),相當(dāng)于得到文件中的數(shù)據(jù)。
            下面這個(gè)例子演示了映射內(nèi)存:
    package nio;

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.nio.MappedByteBuffer;
    import java.nio.channels.FileChannel;

    public class CopyFile {

        
    public static void main(String[] args) throws Exception {

            FileChannel fIChan, fOChan;
            MappedByteBuffer mBuf;

            fIChan 
    = new FileInputStream("buffer.txt").getChannel();
            fOChan 
    = new FileOutputStream("bufferTemp.txt").getChannel();

            mBuf 
    = fIChan.map(FileChannel.MapMode.READ_ONLY, 0, fIChan.size());

            fOChan.write(mBuf);

            fIChan.close();
            fOChan.close();
            
            fIChan 
    = null;
            fOChan 
    = null;
            mBuf 
    = null;

        }


    }

    posted on 2008-10-21 17:44 Loy Fu 閱讀(835) 評(píng)論(0)  編輯  收藏 所屬分類: java
    主站蜘蛛池模板: 精品特级一级毛片免费观看| 4hu四虎免费影院www| 国产美女无遮挡免费视频| 日日狠狠久久偷偷色综合免费| 国产国拍亚洲精品mv在线观看| 99在线精品免费视频九九视| 亚洲av成人中文无码专区| 亚洲午夜久久久久久久久久| 中文字幕乱码免费视频| 成年网在线观看免费观看网址 | 亚洲乱码中文字幕综合234| 日韩免费电影网址| 亚洲第一综合天堂另类专| 亚洲国产精品无码久久久不卡| 欧美a级成人网站免费| 精品一区二区三区高清免费观看| 亚洲国产精品张柏芝在线观看| 亚洲第一区精品观看| 久久精品国产免费观看| 无遮挡免费一区二区三区 | 一个人免费视频在线观看www| 中文无码亚洲精品字幕| 亚洲不卡av不卡一区二区| 免费激情视频网站| 日韩午夜理论免费TV影院| 美女视频黄a视频全免费网站色| 亚洲av色影在线| 亚洲一区二区精品视频| 在线免费一区二区| 亚洲a一级免费视频| 一级毛片正片免费视频手机看| 国产精品亚洲专区在线观看| 久久亚洲一区二区| 国产成人综合亚洲亚洲国产第一页| 性色av无码免费一区二区三区| 免费精品无码AV片在线观看| 中文字幕免费观看视频| 免费精品国自产拍在线播放| 亚洲国产精品18久久久久久| 亚洲欧洲另类春色校园网站| 久久亚洲AV成人出白浆无码国产|