Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 中級開發 >> Android開發進階之NIO非阻塞包(二)

Android開發進階之NIO非阻塞包(二)

編輯:中級開發

有關Android NIO我們主要分為三大類,ByteBuffer、FileChannel和SocketChannel。由於篇幅原因今天android123只對前兩個做說明。NIO和傳統的I/O比較大的區別在於傳輸方式非阻塞,一種基於事件驅動的模式,將會使方法執行完後立即返回,傳統I/O主要使用了流Stream的方式,而在New I/O中,使用了字節緩存ByteBuffer來承載數據。

   ByteBuffer位於java.nio包中,目前提供了Java基本類型中除Boolean外其他類型的緩沖類型,比如ByteBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer和ShortBuffer  。同時還提供了一種更特殊的映射字節緩沖類型MappedByteBuffer。在傳統IO的輸入輸出流中,InputStream中只提供了字節型或字節數組的訪問對應NIO就是ByteBuffer,但是處理傳統的DataInputStream的int等類型,就是IntBuffer,但是緩沖類型並沒有提供UTF這樣的類型處理,所以我們仍然需要使用ByteBuffer處理字符串,但是NIO提供了一個封裝的類在Java.nio.charset包中,通過字符的編碼CharsetEncoder和解碼CharsetDecoder類來處理字符串,同時這些類可以方便轉換編碼比如GBK或UTF等等。

  一、ByteBuffer類

  1) 實例化

  直接使用ByteBuffer類的靜態方法static ByteBuffer allocate(int capacity) 或 static ByteBuffer allocateDirect(int capacity)  這兩個方法來分配內存空間,兩種方法的區別主要是後者更適用於繁復分配的字節數組。而 put(ByteBuffer src) 可以從另一個ByteBuffer中構造,也可以通過wrap方法從byte[]中構造,具體參考下面的類型轉化內容。

  2) 類型轉化

   ByteBuffer可以很好的和字節數組byte[]轉換類型,通過執行ByteBuffer類的final byte[]  array() 方法就可以將ByteBuffer轉為byte[]。從byte[]來構造ByteBuffer可以使用wrap方法,目前android或者說Java提供了兩種重寫方法,比如為static ByteBuffer  wrap(byte[] array)  和 static ByteBuffer  wrap(byte[] array, int start, int len)  ,第二個重載方法中第二個參數為從array這個字節數組的起初位置,第三個參數為array這個字節數組的長度。

  3) 往ByteBuffer中添加元素

  目前ByteBuffer提供了多種put重寫類型來添加,比如put(byte b) 、putChar(char value) 、putFloat(float value) 等等,需要注意的是,按照Java的類型長度,一個byte占1字節,一個char類型是2字節,一個float或int是4字節,一個long則為8字節,和傳統的C++有些區別。所以內部的相關位置也會發生變化,同時每種方法還提供了定位的方法比如ByteBuffer  put(int index, byte b) 

  4) 從ByteBuffer中獲取元素

  同上面的添加想法,各種put被換成了get,比如byte  get()  、float  getFloat()  ,當然了還提供了一種定位的方式,比如double  getDouble(int index) 

  5) ByteBuffer中字節順序

  對於Java來說默認使用了BIG_ENDIAN方式存儲,和C正好相反的,通過

  final ByteOrder  order() 返回當前的字節順序。

  final ByteBuffer  order(ByteOrder byteOrder)  設置字節順序,ByteOrder類的值有兩個定義,比如LITTLE_ENDIAN、BIG_ENDIAN,如果使用當前平台則為ByteOrder.nativeOrder()在android中則為 BIG_ENDIAN,當然如果設置為order(null) 則使用LITTLE_ENDIAN。

  二、FileChannel類

   在NIO中除了Socket外,還提供了File設備的通道類,FileChannel位於Java.nio.channels.FileChannel包中,在android SDK文檔中我們可以方便的找到,對於文件復制我們可以使用ByteBuffer方式作為緩沖,比如

  String infile = "/sdcard/cwj.dat";
  String outfile = "/sdcard/android123-test.dat";

    FileInputStream fin = new FileInputStream( infile );
    FileOutputStream fout = new FileOutputStream( outfile );

    FileChannel fcin = fin.getChannel();
    FileChannel fcout = fout.getChannel();

    ByteBuffer buffer = ByteBuffer.allocate( 1024 ); //分配1KB作為緩沖區

    while (true) {
    buffer.clear(); //每次使用必須置空緩沖區

      int r = fcin.read( buffer );

      if (r==-1) {
        break;
      }

   buffer.flip(); //寫入前使用flip這個方法

      fcout.write( buffer );
    }

   flip和clear這兩個方法是Java.nio.Buffer包中,ByteBuffer的父類是從Buffer類繼承而來的,這點Android123要提醒大家看Android SDK文檔時注意Inherited Methods,而JDK的文檔就比較直接了,同時復制文件使用FileChannel的transferTo(long position, long count, WritableByteChannel target) 這個方法可以快速的復制文件,無需自己管理ByteBuffer緩沖區。明天android開發網介紹NIO主要的Socket相關的內容。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved