1. 程式人生 > >Android開發進階之NIO非阻塞包(二)

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

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

   ByteBuffer位於java.nio包中,目前提供了Java基本型別中除Boolean外其他型別的緩衝型別,比如ByteBufferDoubleBufferFloatBufferIntBuffer

LongBufferShortBuffer  。同時還提供了一種更特殊的對映位元組緩衝型別MappedByteBuffer。在傳統IO的輸入輸出流中,InputStream中只提供了位元組型或位元組陣列的訪問對應NIO就是ByteBuffer,但是處理傳統的DataInputStreamint等型別,就是IntBuffer,但是緩衝型別並沒有提供UTF這樣的型別處理,所以我們仍然需要使用ByteBuffer處理字串,但是NIO提供了一個封裝的類在java.nio.charset包中,通過字元的編碼CharsetEncoder和解碼CharsetDecoder類來處理字串,同時這些類可以方便轉換編碼比如
GBKUTF等等。

一、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的型別長度,一個byte1位元組,一個char型別是2位元組,一個floatint4位元組,一個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_ENDIANBIG_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 );
    }

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

相關推薦

Android開發NIO阻塞()

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

Android開發NIO阻塞(三)

有關Android NIO的精髓主要用於高負載的Socket網路傳輸,相對於傳統I/O模型的Socket傳輸方式的優勢,我們已經在 Android開發進階之NIO非阻塞包(一) 中講到了,這裡不再贅述,一起來看看Android NIO有關Socket操作提供的類吧: 一、S

Netty基礎篇NIO 阻塞通訊(6)

1、Tcp網路非阻塞通訊 //客戶端 @Test public void client() throws IOExcept

Android 動畫動畫切換

ram 屏幕 pre 退出 tac 旋轉動畫 utf 轉動 XML 一、Activity切換動畫   在Android開發中,經常會遇到Activity之間切換效果,下面介紹一下,Activity左右滑動切換效果。在Android2.0以後版本,在Activity中添加了

Java開發

為我 變量 kafka 自然 ges 想想 javaweb 目前 沒有 背景一 我接觸Java開發已經一年多了了。 從剛開始生澀地接觸語法,惹得編譯器報各種語法錯誤;到接觸OOD的思想,封裝、繼承、多態,懵懵懂懂地聽說著它們;再到學習Web開發,想著這些也許並不重要,實際用

Python學習----第七模塊筆記(Web開發Django數據庫操作)

long 機制 idt 4.5 gen git 表之間 protoc 小數 4、Django ORM 4.1、連接數據庫 創建Django工程後運行該工程,會在工程根目錄下創建db.sqlite3文件,為Django自帶的sqlite3數據庫(Django自帶的功能也需要數

Android高階自定義View

前言 在網上看到一張圖,花了些時間自己嘗試著寫了一個自定義View,裡面涉及到了自定義屬性、自定義View padding屬性的處理、畫筆(Paint)和畫布(Canvas)的使用、解析度適配問題、效能問題、屬性動畫等,覺得還是有些東西值的記錄一下的,效果圖如下: 自定義屬

Android開發——使用Dagger2

前言 關於Dagger2的學習,首先看的官方文件,確實看不懂。然後搜尋網路上的介紹博文,不乏一些講得比較好的,如這個。但終究不夠透徹,還是得回頭研究官方文件。本文不僅僅是翻譯,而是記錄了自己對官方文件的理解。 提供依賴的兩種方式 使用@Inject註解構造器 class

Android開發——測試

導言 每次使用Android Studio建立一個新的工程,都會看到類似如下的目錄結構: 我們編寫的Java程式碼全部放在最上面的包中,下面兩個使用紅線圈中的包總是沒有用過,僅僅知道他們是用於放置測試程式碼的。標註為androidTest的包放置UI相關的測試,標註為test

HenCoder Android 開發: 自定義 View 1-1 繪製基礎

自定義繪製概述 二話不說,我反手就是一個視訊:(視訊掛了,先直接點到優酷去看吧:優酷連結) 首先總結一下視訊中的關鍵點: 自定義繪製的方式是重寫繪製方法,其中最常用的是 onDraw() 繪製的關鍵是 Canvas 的使用 Canvas 的繪製類方法: drawXX

Android高階 TextInputLayout用法

TextInputLayout見名知義與文字輸入有關係,TextInputLayout控制元件通過內嵌EditText來實現輸入文字時,根據預先設定的屬性向使用者展示相應的提醒文字並附有酷炫的動畫效果。例如,當文字框裡的字元長度大於10的時候自動給使用者提示,無需編寫額外的程

安卓開發RxJava在實際專案中使用--第二篇

關於RxJava原理分析,請參考仍物線寫的文章—-給 Android 開發者的 RxJava 詳解。本文不對原理作過多的分析,從最快上手的角度,讓開發者使用起來,當我們有實踐經驗後回過頭來看原理分析會更清晰。 本系列共有三篇文章,分別關於Rxjava的基礎使用

前端工程師開發

var str="www.baidu.com/?page"; // 1、字串剪裁 str.substring(0, str.indexof("?page")); // 2、正則表示式 str.replace(/?page/, ""); // 3、字串分拆、合併 str.split("?page").join(

指尖上行--移動前端開發路(讀書筆記)----1.1頁面佈局

chapter 1 移動頁面開發 頁面佈局 頁面除錯 常用庫和框架 1.1 頁面佈局 1.1.1 Vieport(視口,檢視視窗) 裝置畫素 物理畫素:螢幕解析度; 裝置獨立畫素:CSS畫素(eg:IPhone5 CSS畫素是320*568p

Android開發:Activity和程序的回收和狀態恢復

不管是安卓的官方文件還是原始碼註釋,處處可見“從 Activity A 跳到 Activity B,當系統記憶體不足時 A 可能會被回收……”,而且沒有明確說明 A 和 B 是否屬於同一個 app 或程序。 但是,在官方給的 Activity 生命週期圖中

Android開發-:Json字串轉換為java物件的各種實現方法[json_lib框架、Gson、org.json]

JSON (JavaScript Object Notation) 是一種輕量級的資料交換格式。易於人閱讀和編寫。同時也易於機器解析和生成。它基於JavaScript Programming Language, Standard ECMA-262 3rd Edition

指尖上行--移動前端開發路(讀書筆記)----2.1動畫形式

chapter 2 技術創意形式 動畫形式 移動裝置 Web API 詳解 WebVR 創意點 2.1 動畫形式 2.1.1 CSS3 CSS3 Cascading Style Sheets 層疊樣式表。 CSS3是CSS技術的一個升級版本,

一、web專案開發分模組管理專案通用模組

  以前的web專案都是統一一個工程,其他人員在這個專案拉取分支進行開發,但是若需要多個人協作同時進行開發時,會造成各種各樣的問題。為了解決這些問題,按照業務邏輯進行區分,將一個專案按照多個模組進行構建。 (一)所有專案的父模組“parent”   父模組的

指尖上行--移動前端開發路(讀書筆記)----1.3常用庫和框架

chapter 1 移動頁面開發 頁面佈局 頁面除錯 常用庫和框架 1.3 常用庫和框架 1.3.1 jQuery Mobile jQuery Mobile是jQuery 框架的一個元件(而非jquery的移動版本)。這個框架已經很老了,本人

大資料開發HBase開發例項介紹

這周學習了HBase的開發例項,主要有一些HBase API的使用。(文中的程式碼,是經過實際執行有效的,只擷取片段,關於全部的可參考前一篇文章中全域性變數的設定,關於執行環境也與前一篇一樣) 一、HBase基本操作 1.追加插入-Append 在原有的value中追加值,