乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      java.nio.*

       鳳舞天煌 2007-11-12

                   JDK 1.4的java.nio.*包中引入了新的JavaI/O類庫,其目的在于提高速度。(實際上,舊的I/O包已經(jīng)使用nio重新實現(xiàn)過,以便充分利用這種速度,即使我們不顯式地用nio編寫代碼,也能從中受益!

                   nio速度的提高來自于所使用的結(jié)構(gòu)更接近于操作系統(tǒng)執(zhí)行I/O的方式(Java執(zhí)行I/O接近于操作系統(tǒng)執(zhí)行I/O,所以速度得到了提高):通道和緩沖器。我們可以把它想象成一個煤礦,通道是一個包含煤層(數(shù)據(jù))的礦藏,而緩沖器則是派送到礦藏的卡車。卡車載滿煤炭而歸,我們再從卡車上獲得煤炭。也就是說,我們要讀書到數(shù)據(jù),并沒有直接和通道交互;只是和緩沖器交互,并把緩沖器派送到通道。通道要么從緩沖器獲得數(shù)據(jù),要么向緩沖器發(fā)送數(shù)據(jù)!

                   唯一直接與通道交互的緩沖器是ByteBuffer,它是java.nio里面的類:通過告知分配多少存儲空間來創(chuàng)建一個ByteBuffer對象,并且還有一個方法選擇集,用以原始的字節(jié)形式或基本數(shù)據(jù)類型輸出和讀取數(shù)據(jù)。但是沒辦法輸出或讀取對象,即使是字符串對象也不行;

                ByteBuffer是一個抽象類,不能直接創(chuàng)建實例,可以調(diào)用該類的static方法allocate(int capacity)來創(chuàng)建它的一個新緩沖區(qū),該緩沖區(qū)的位置將為零,其界限將為其容量,其標記是不確定的。它將具有一個底層實現(xiàn)數(shù)組,且其 數(shù)組偏移量將為零。

                 關于通道,這里介紹一個文件通道FileChannel,它也是一個抽象類,也不能直接創(chuàng)建實例。舊的I/O類庫中有本個類被修改過了,可以用它們的getChannel()來返回一個FileChannel對象(更確切的說應該是返回FileChannel的一個匿名子類的對象)。這三個能返回FileChannel的類是:FileInputStream,FileOutputStream,RandomAccessFile 。值得注意的是它們都是字節(jié)流的,Reader與Writer這兩個處理字符流的類不能用于通道,不過java,nio.channels.Channels類提供了實用方法,用以在通道中產(chǎn)生Reader與Writer(想了解更多請查API文檔,這里不介紹)!
      ===========================================================================================
      緩沖區(qū)是特定基本類型元素的線性有限序列。除內(nèi)容外,緩沖區(qū)的基本屬性還包括容量、限制和位置:

      緩沖區(qū)的容量 是它所包含的元素的數(shù)量。緩沖區(qū)的容量不能為負并且不能更改。

      緩沖區(qū)的限制 是第一個不應該讀取或?qū)懭氲脑氐乃饕?。緩沖區(qū)的限制不能為負,并且不能大于其容量。

      緩沖區(qū)的位置 是下一個要讀取或?qū)懭氲脑氐乃饕?。緩沖區(qū)的位置不能為負,并且不能大于其限制。

        因此,我們從緩沖區(qū)讀書數(shù)據(jù),其實是從此緩沖區(qū)的“位置”處一直讀到“限制”處!


      ============================================================================================
                 關于緩沖器ByteBuffer,最令人捉摸不清的可能是它的三個方法:flip();clear();remind()
      這三個方法一般是和FileChannel的read(ByteBuffer bf)與write(ByteBuffer bf)混合在一起使用的!
         
                     FileChannel的read(ByteBuffer bf):將字節(jié)序列從FileChannel讀入給定的緩沖區(qū)ByteBuffer bf 中!讀完以后,bf的當前位置就是從FileChannel中讀取的字節(jié)個數(shù)!
                    同理,我們應該可以很容易想象出write(ByteBuffer bf)它就是用來將字節(jié)序列從給定的緩沖區(qū)ByteBuffer bf寫入通道FileChannel。
          
                    ByteBuffer的flip():反轉(zhuǎn)此緩沖區(qū),將限制設置為當前位置然后將位置設置為 0 !
           
                     ByteBuffer的clear();“清除”此緩沖區(qū),將位置設置為 0,將限制設置為容量!
      此方法不能實際清除緩沖區(qū)中的數(shù)據(jù),但從名稱來看它似乎能夠這樣做,這樣命名是因為它多數(shù)情況下確實是在清除數(shù)據(jù)時使用。因為調(diào)用該方法后,我們一般都會調(diào)用FileChannel.read(buff)或者buff.put()來把新的數(shù)據(jù)放到buff中,此時原來的內(nèi)容就會被新的內(nèi)容所覆蓋!也不是全部覆蓋,而是覆蓋掉新數(shù)據(jù)所包含的字節(jié)數(shù)!所以看起來好象就是原來的內(nèi)容被刪除一樣!

                   remind(),重繞此緩沖區(qū),將位置設置為 0 并丟棄標記。此方法與flip()的區(qū)別是:remind()不會把限制設置為當前位置,而是保持限制不變!與clear()的區(qū)別是:remind()不會把限制設置為容量,而是保持限制不變!

      ==========================================================================================
      講了這么多,你們不暈,我都暈了,那么現(xiàn)在來點實際的代碼,以幫助理解!

      //例一:
      import java.nio.channels.*;
      import java.io.*;

      public class GetChannel {
                 private static final int BSIZE = 1024;
                 public static void main(String[] args) throws Exception {
                   // Write a file:
                   FileChannel fc =
                     new FileOutputStream("data.txt").getChannel();
                   fc.write(ByteBuffer.wrap("Some text ".getBytes()));
                   fc.close();
                   // Add to the end of the file:
                   fc =
                     new RandomAccessFile("data.txt", "rw").getChannel();
                   fc.position(fc.size()); //
      將通道位置移動到最后,以便我們在通道后面繼續(xù)寫入新數(shù)據(jù)
                   fc.write(ByteBuffer.wrap("Some more".getBytes()));
                   fc.close();
                   // Read the file:
                   fc = new FileInputStream("data.txt").getChannel();
                   ByteBuffer buff = ByteBuffer.allocate(BSIZE);
                   fc.read(buff);
      //把通道中的字節(jié)序列讀入buff中

                   //進行此操作后,buff的位置移動了從FileChannel中讀取的字節(jié)個數(shù)!

                   buff.flip();           //為下面的buff.get()做準備,將buff的限制設置為當前位置,然后將位置設置為 0
                  //因為我們從buff讀取,是從此buff的位置處一直讀到限制處!
                   while(buff.hasRemaining())
                     System.out.print((char)buff.get());
                 }
      } /* Output:
      Some text Some more
      *///:~
      =========================================================================================
      //例二:

      // Copying a file using channels and buffers
      // {Args: ChannelCopy.java test.txt}
      import java.nio.*;
      import java.nio.channels.*;
      import java.io.*;

      public class ChannelCopy {
                 private static final int BSIZE = 1024;
                 public static void main(String[] args) throws Exception {
                   if(args.length != 2) {
                     System.out.println("arguments: sourcefile destfile");
                     System.exit(1);
                   }
                   FileChannel
                     in = new FileInputStream(args[0]).getChannel(),
                     out = new FileOutputStream(args[1]).getChannel();
                   ByteBuffer buffer = ByteBuffer.allocate(BSIZE);
                   while(in.read(buffer) != -1) {           //buffer 用來向FileChannel讀取數(shù)據(jù)

               //其實此循環(huán)只會執(zhí)行一次,因為執(zhí)行一次就會把FileChannel中的全部數(shù)據(jù)都讀到buffer中
                     buffer.flip(); // 為通道寫入做準備
                     out.write(buffer); //buffer 用來向FileChannel寫入數(shù)據(jù)
                     buffer.clear();           // 為通道再次讀取做準備
                   }
                 }
      } ///:~

       

      ============================啟示================================

      當對flip(),clear(),remind()不是很理解而正在考慮某個地方是否需要這三個方法時,我們還可以調(diào)用limit(),position(),remainning()等方法來進行調(diào)試。

      public final int limit()
      返回此緩沖區(qū)的限制。
      public final int position()
      返回此緩沖區(qū)的當前位置。
      public final int remaining()
      返回當前位置與限制之間的元素數(shù)。

      ======================================================================

      上面的兩個例子,是因為有FileChannel的read()或者write(),以至把ByteBuffer中的位置移動了相應的字節(jié)數(shù)。然后調(diào)用flip時,就把限制設置為當前位置。此時的position就不為0了。下面的例子中,沒有FileChannel的參與,當前位置也就沒有了變化,此時,若再調(diào)用flip,由于當前位置是0,設置為限制后,限制也變成0,若我們要從限制為0的ByteBuffer中讀取數(shù)據(jù),此時就什么也沒讀到,可能還會拋出異常。那么解決的方法就是調(diào)用rewind(),此方法,只是把位置設置為0,而不會改變其限制,這時,限制就仍為容量。因為用ByteBuffer的static allocated()時,新緩沖區(qū)的位置將為零,其限制將為其容量!

      另外,調(diào)用ByteBuffer的get()與put()時,會把position移動一個字節(jié)!而調(diào)用這兩個方法的帶參數(shù)版本則不會改變position的值,這里還要區(qū)別一下兩種情況的put方法:

         情況一:

          ByteBuffer bb = ByteBuffer.allocate(1024);
          CharBuffer cb = bb.asCharBuffer(); //創(chuàng)建ByteBuffer的Char視圖

          cb.put("Hwdy!"); ////字符串中的每個字符占1個字節(jié)!共占5個字節(jié)!所以此句會使position移動5個字節(jié)!

       

      ===================================================================

      情況二:

      ByteBuffer bb = ByteBuffer.allocate(BSIZE);
          bb.asCharBuffer().put("Howdy"); //用這種形式來創(chuàng)建視圖不會移動bb的position

           print(bb.position()); //所以此處的postion值為0

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多