[英]How to aggregate two Strings and a List<byte[]> into a single byte[] and then extract them
我需要將2個字符串和一個列表聚合到一個byte []中,以便通過網絡發送它(使用具有send(byte [])函數的特殊庫。
然后,在另一端,我需要取回3個不同的對象。
我已經做了一個丑陋的實現,但是非常慢。 基本上,我要做的是
public byte[] myserializer(String dataA, String dataB, List<byte[]> info) {
byte[] header = (dataA +";" + dataB + ";").getBytes();
int numOfBytes = 0;
for (byte[] bs : info) {
numOfBytes += bs.length;
}
ByteArrayOutputStream b = new ByteArrayOutputStream();
ObjectOutputStream o;
try {
o = new ObjectOutputStream(b);
o.writeObject(info);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] data = b.toByteArray();
int length = header.length + data.length;
byte[] headerLength = (new Integer(header.length)).toString()
.getBytes();
byte[] pattern = ";".getBytes();
int finalLength = headerLength.length + pattern.length + length;
byte[] total = new byte[finalLength];enter code here
total = // Copy headerLength, header and total into byte[] total
return return;
本質上,我正在創建一種看起來像這樣的框架
HEADER INFO
(-----------------------------------------------)( ----------------------------------)HEADER_LENGHT; DATA_A; DATA_B; SERIALIZED_LIST_OBJECT
然后,在接收器端,我進行逆過程,就是“全部”。 這是可行的,但它的效率很低而且很丑陋。
有什么建議嗎? 最佳做法? 有想法嗎?
哦...還有一點需要注意:這也必須適用於J2SE和Android
非常感謝高級!!
將其全部寫入ByteArrayOutputStream
,並在其周圍使用ObjectOutputStream來序列化字符串和列表,然后調用將BAOS轉換為byte []數組的方法。 在另一端,進行逆運算。
或定義一個包含{String, String, List}
元組的可序列化對象,只需使用ObjectOutputStream
序列化,然后使用ObjectInputStream
反序列化即可。 簡單得多。
或者只做三個發送。 TCP是字節流,消息之間沒有邊界,字節均按順序到達。 如果要保留對網絡的寫入,請在寫入List
之后插入BufferedOutputStream
並將其刷新。
這是一種序列化字節數組並在另一端反序列化的簡單方法。 需要注意的是該方法只接受類型的一個參數List<byte[]>
既然你的論點dataA
和dataB
的類型為String
,你可以簡單地假定兩個第一byte[]
列表中的元素是這兩個說法。 我相信這比通過ObjectOutputStream
對象序列化要快得多,並且在另一端反序列化的速度也會更快。
public class ByteListSerializer {
static private final int INT_SIZE = Integer.SIZE / 8;
static public void main(String...args) {
ByteListSerializer bls = new ByteListSerializer();
// ============== variable declaration =================
String dataA = "hello";
String dataB = "world";
List<byte[]> info = new ArrayList<byte[]>();
info.add(new byte[] {'s','o','m','e'});
info.add(new byte[] {'d','a','t','a'});
// ============= end variable declaration ==============
// ======== serialization =========
info.add(0, dataA.getBytes());
info.add(1, dataB.getBytes());
byte[] result = bls.dataSerializer(info);
System.out.println(Arrays.toString(result));
// ======== deserialization ========
List<byte[]> back = bls.dataDeserializer(result);
String backDataA = new String(back.get(0));
String backDataB = new String(back.get(1));
back.remove(0);
back.remove(0);
// ============ print end result ============
System.out.println(backDataA);
System.out.println(backDataB);
for (byte[] b : back) {
System.out.println(new String(b));
}
}
public byte[] dataSerializer(List<byte[]> data) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteBuffer lenBuffer = ByteBuffer.allocate(4);
try {
for (byte[] d : data) {
lenBuffer.putInt(0, d.length);
out.write(lenBuffer.array());
out.write(d);
}
} catch (IOException e) {
e.printStackTrace();
}
// wrap this
byte[] dataBuffer = new byte[out.size() + 4];
lenBuffer.putInt(0, out.size());
System.arraycopy(lenBuffer.array(), 0, dataBuffer, 0, 4);
System.arraycopy(out.toByteArray(), 0, dataBuffer, 4, out.size());
return dataBuffer;
}
public List<byte[]> dataDeserializer(byte[] data) {
if (data.length < INT_SIZE) {
throw new IllegalArgumentException("incomplete data");
}
ByteBuffer dataBuffer = ByteBuffer.wrap(data);
int packetSize = dataBuffer.getInt();
if (packetSize > data.length - INT_SIZE) {
throw new IllegalArgumentException("incomplete data");
}
List<byte[]> dataList = new ArrayList<byte[]>();
int len, pos = dataBuffer.position(), nextPos;
while (dataBuffer.hasRemaining() && (packetSize > 0)) {
len = dataBuffer.getInt();
pos += INT_SIZE;
nextPos = pos + len;
dataList.add(Arrays.copyOfRange(data, pos, nextPos));
dataBuffer.position(pos = nextPos);
packetSize -= len;
}
return dataList;
}
}
框架構造為
- 4 bytes: the total bytes to read (frame size = [nnnn] + 4 bytes header)
| - 4 bytes: the first chunk size in bytes
| | - x bytes: the first chunk data
| | |
| | | - 4 bytes: the n chunk size in byte
| | | | - x bytes: the n chunk data
| | | | |
| | | | |
[nnnn][iiii][dddd....][...][iiii][dddd...]
上面的示例將輸出
[0, 0, 0, 34, 0, 0, 0, 5, 104, 101, 108, 108, 111, 0, 0, 0, 5, 119, 111, 114, 108, 100, 0, 0, 0, 4, 115, 111, 109, 101, 0, 0, 0, 4, 100, 97, 116, 97]
hello
world
some
data
請注意 ,幀格式是由byte[]
塊構成的,因此只要您知道塊的順序,就可以對幾乎任何數據集使用這些方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.