最近在android開發用到藍牙,因爲項目是對一些通訊協議進行解析,用到些IO字節流的知識,在這裏做個總結。
Java IO裏面要分清楚兩個基本概念,即字符流和字節流。
先來看一下流的概念:
在程序中所有的數據都是以流的方式進行傳輸或保存的,程序需要數據的時候要使用輸入流讀取數據,而當程序需要將一些數據保存起來的時候,就要使用輸出流完成。
程序中的輸入輸出都是以流的形式保存的,流中保存的實際上全都是字節文件。
網上這方面的文章很多,這篇主要介紹解析協議時用到的IO知識。在java.io包中操作文件內容的主要有兩大類:字節流、字符流。
在我的程序裏面,藍牙連上之後協議在傳輸過程中是以字節形式進行傳輸,因此本篇博客將主要介紹字節流。
字節流:
例子
在字節流中輸出數據主要是使用OutputStream完成,輸入使的是InputStream。
InputStream in = null;
OutputStream out = null;
try{
in = btSocket.getInputStream();
out = btSocket.getOutputStream();
}catch(IOException e){
}
接下來用in.read(buf, length)方法便可讀到字節流。out.write(buf)方法可以將字節輸出。這裏的buf是一個byte數組,在使用字節流的過程中,byte數組是非常常用,使用方法參考如下:
byte[] test = new byte[2];
test[0] = (byte)0xfd;
test[1] = (byte)0x55;
進制轉換
對字節進行操作時,有幾個操作非常實用。
1. 十六進制轉十進制 byteToInteger。
2. 十進制轉十六進制 integerToByte。
3. String轉十六進制 StringToBytes。
4. 十六進制轉String bytesToHexString。
代碼分別如下:
int byteToInteger(byte b)
{
int value;
value = b & 0xff;
return value;
}
因爲Java裏面byte是有符號數,一個字節8位,其中最左邊的位數代表符號位。因此byte值範圍爲-128~127,而int是32位,因此如果直接將byte賦值給int,當byte的符號位爲1時,int裏面的前24位會被賦值成1,因此出來的結果便不是你想要的。故將byte的值先與0x000000ff進行&操作,將前24位復位成0,結果便是正確。
public static final void StringToBytes(String in, byte[] b) throws Exception{
if (b.length < in.length() / 2) {
throw new Exception("byte array too small");
}
int j=0;
StringBuffer buf = new StringBuffer(2);
for (int i=0; i
buf.insert(0, in.charAt(i));
buf.insert(1, in.charAt(i+1));
int t = Integer.parseInt(buf.toString(),16);
b[j] = (byte)(t & (0xff));
i++;
buf.delete(0,2);
}
}
public static final String bytesToHexString(byte[] bArray) {
StringBuffer sb = new StringBuffer(bArray.length);
String sTemp;
for (int i = 0; i < bArray.length; i++) {
sTemp = Integer.toHexString((int)(0xFF & bArray[i]));
if (sTemp.length() < 2)
sb.append(0);
sb.append(sTemp.toUpperCase());
}
return sb.toString();
}
總結:
流使用完需要close,一般情況下,儘量使用比如BufferedInputStream之類的buffer減少IO次數,提升性能。當然,BufferedInputStream會自動將字節轉換成字符,在協議解析程序裏面失去了意義。不過試用於字節流的Buffer也有許多,大家可以查找API。
參考資料:
http://xiaolongfeixiang.iteye.com/blog/648700
http://lavasoft.blog.51cto.com/62575/95387
http://java.sun.com/developer/technicalArticles/Streams/ProgIOStreams/