上一篇 学习了,ByteBuffer 的一些重要的 Api,这篇借着所学习的知识完成一个小小的Demon
一般我们的数据传输都是明文传输,采用各种各样的格式,如 JSON,XML等。现在就用上篇所学的 Api 来完成一个定制的字节流数据传输格式。即把我们所需要传输的数据以特定的格式(有一定的加密效果)生成,再以特定的格式解析。需要注意的是这个Demon有很大的改进空间。目前只支持以固定顺序读取数据,可以继续改进,读取任意一个数据(重新定义数据格式)。
先来介绍一下基本思路。
- 制定特定的数据格式
| type | length | content |
type 单个数据的格式(见代码)
length 数据的长度或 array类型的length。基本数据类型没有长度这个字段。
content 即内容(byte 字节流) - 以特定的顺序写入数据
writeInt()
writeIntArray()
writeDouble()
... - 以特定的顺序读取数据
package com.zsy.nio;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Arrays;
public class NIOTraining {
public static void main(String[] args) throws UnsupportedEncodingException, IOException {
TransData transData = new TransData();
byte[] bytes = transData
.writeInt(165)
.writeDouble(165.2)
.writeString("hello world!")
.writeIntArray(new int[] {85,89,56})
.writeStringArray(new String[] {"zhongguo","nanjing","Java"})
.getData();
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
while (byteBuffer.hasRemaining()) {
switch (byteBuffer.get()) {
case TransData.TYPE_INT:
System.out.println(byteBuffer.getInt());
break;
case TransData.TYPE_DOUBLE:
System.out.println(byteBuffer.getDouble());
break;
case TransData.TYPE_STRING:
int length = byteBuffer.getInt();
System.out.println(new String(byteBuffer.array(),byteBuffer.position(), length, "UTF-8"));
byteBuffer.position(byteBuffer.position() + length);
break;
case TransData.TYPE_ARRAY_INT:
int len = byteBuffer.getInt();
int[] results = new int[len];
for(int i=0; i<len; i++) {
results[i] = byteBuffer.getInt();
}
System.out.println(Arrays.toString(results));
break;
case TransData.TYPE_ARRAY_STRING:
int stringsLength = byteBuffer.getInt();
String[] strings = new String[stringsLength];
for(int i=0; i<stringsLength; i++) {
int stringLen = byteBuffer.getInt();
strings[i] = new String(byteBuffer.array(), byteBuffer.position(), stringLen, "UTF-8");
byteBuffer.position(byteBuffer.position() + stringLen);
}
System.out.println(Arrays.toString(strings));
break;
}
}
}
/**
* |type|length|content| type 1 byte length 4 byte 基本类型不需要 length
*
* @author zhaoxiaosi
*
*/
static class TransData {
private static final byte TYPE_INT = 1;
private static final byte TYPE_DOUBLE = 2;
private static final byte TYPE_STRING = 3;
private static final byte TYPE_ARRAY_STRING = 4;
private static final byte TYPE_ARRAY_INT = 5;
private static final byte TYPE_ARRAY_DOUBLE = 6;
private ByteArrayOutputStream out = new ByteArrayOutputStream();
public TransData writeInt(int content) {
out.write(TYPE_INT);
out.write(content >>> 24);
out.write(content >>> 16);
out.write(content >>> 8);
out.write(content);
return this;
}
public TransData writeIntArray(int[] ints) {
out.write(TYPE_ARRAY_INT);
writeLength(ints.length);
for(int i: ints) {
out.write(i >>> 24);
out.write(i >>> 16);
out.write(i >>> 8);
out.write(i);
}
return this;
}
public TransData writeStringArray(String[] strings) throws IOException {
out.write(TYPE_ARRAY_STRING);
writeLength(strings.length);
for(String string: strings) {
byte[] bytes = string.getBytes("UTF-8");
writeLength(bytes.length);
out.write(bytes);
}
return this;
}
public TransData writeDouble(double content) {
long value = Double.doubleToRawLongBits(content);
out.write(TYPE_DOUBLE);
out.write((byte) (int)value >>> 56);
out.write((byte) (int)value >>> 48);
out.write((byte) (int)value >>> 40);
out.write((byte) (int)value >>> 32);
out.write((byte) (int)value >>> 24);
out.write((byte) (int)value >>> 16);
out.write((byte) (int)value >>> 8);
out.write((byte) (int)value);
return this;
}
public TransData writeString(String content) throws UnsupportedEncodingException, IOException {
out.write(TYPE_STRING);
byte[] bytes = content.getBytes("UTF-8");
writeLength(bytes.length);
out.write(bytes);
return this;
}
private void writeLength(int length) {
out.write(length >>> 24);
out.write(length >>> 16);
out.write(length >>> 8);
out.write(length);
}
public byte[] getData() {
return out.toByteArray();
}
}
}
output
165
2.16443570729E-312
hello world!
[85, 89, 56]
[zhongguo, nanjing, Java]
网友评论