Java IO字符流和字节流
最近在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;
}
byte integerToByte(int a)
{
byte b;
b = (byte)(a & 0xFF);
return b;
}
因为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<in.length(); i++, j++) {
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/
http://www.cnblogs.com/lich/archive/2011/12/11/2283700.html