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