【Android】TVL資料流解析
阿新 • • 發佈:2019-02-13
tlv資料格式:type(1位元組)+length(2位元組)+value(有效資料);
長度規定(雙方規定的):{低位、高位} ,例:{(byte)0x5A,(byte)0x00} 轉成int = 0x005A = 90 ;
package com.example.util; import android.util.Log; import java.io.IOException; import java.io.InputStream; /** * @author alan * Created by Administrator on 2018/4/8 0008. */ public class TLVUtil { public interface CallBack { void getValue(String valueData); } ; /** * 從TLV格式資料流解析出中的value * * @param inputStream */ public void parseValueFromTLVInputStream(InputStream inputStream, CallBack callBack) throws Exception { try { boolean isOnce = true;//開始一次tlv資料讀取 StringBuilder builder = new StringBuilder(); int leftPartSize = 0;//剩餘長度 while (true) { Thread.sleep(50); if (inputStream == null) return; if (inputStream.available() > 0) {//收到一次推送的資料 byte[] valueArray; int available = inputStream.available(); //繼續讀取value(上次tlv不完整) if (!isOnce) { // byte[] buf = new byte[leftPartSize]; // int len = inputStream.read(buf); // String part = new String(buf, 0, len); // builder.append(part); if (leftPartSize > available) {//剩下已知的 > 讀取的,還需要繼續讀取 leftPartSize = leftPartSize - available; //取vaule資料 valueArray = new byte[available]; int read = inputStream.read(valueArray); String valueStr = new String(valueArray, 0, read); builder.append(valueStr); continue; } else {//剩下已知的 =< 讀取的 //拆分出最後已知的 valueArray = new byte[leftPartSize]; int read = inputStream.read(valueArray); String valueStr = new String(valueArray, 0, read); // 組成完整value builder.append(valueStr); String allValue = builder.toString(); builder = new StringBuilder();//清空 //<處理> callBack.getValue(allValue); //開始下次tlv處理 isOnce = true; available = available - leftPartSize; leftPartSize = 0; builder = new StringBuilder();//清空 if (available == 0) {//沒資料了,重新讀流 continue; } Log.e("TAG", "下次tlv處理-available->" + available); } } //tlv處理 while (isOnce) { //取type byte[] typeArray = new byte[1]; inputStream.read(typeArray); int type = (typeArray[0] & 0xff);//第一個位元組表示type(byte轉int) //取length(2位元組) byte[] lengthArray = new byte[2]; inputStream.read(lengthArray); int length = bytesTolength(lengthArray); Log.e("TAG", "tlv-length->" + length); //判斷 if (available > (length + 3)) {//推過來的 》已知的 ,繼續讀剩下新的tlv isOnce = true; leftPartSize = available - (length + 3); available = leftPartSize; //取vaule資料(完整) valueArray = new byte[length]; int read = inputStream.read(valueArray); String valueStr = new String(valueArray, 0, read); // builder.append(valueStr); //<處理> callBack.getValue(valueStr); } else if (available == (length + 3)) { isOnce = true; //取vaule資料(完整) valueArray = new byte[length]; int read = inputStream.read(valueArray); String valueStr = new String(valueArray, 0, read); // builder.append(valueStr); //<處理> callBack.getValue(valueStr); break; } else {//available < (length + 3) 讀取不完整,需要繼續讀取 isOnce = false; leftPartSize = (length + 3) - available; //取vaule資料(不完整) valueArray = new byte[available - 3]; int read = inputStream.read(valueArray); String valueStr = new String(valueArray, 0, read); builder.append(valueStr); break; } }//end while-isOnce } } } catch (IOException e) { e.printStackTrace(); Log.e("TAG", "client connected name--->" + Thread.currentThread().getName() + " e-->" + e.getMessage()); // Log.e("TAG", "異常-tlv解析->" + e.getMessage()); } } /** * byte陣列轉長度值 {低位,高位} [參照文件規定] * * @param array * @return */ public int bytesTolength(byte[] array) { int length = 0; if (array != null) { length = ((array[0] & 0xff)) | ((array[1] & 0xff) << 8); } return length; } }