我有一个奇怪的问题。基本上,我使用的是仅将输入作为 byte[] 的队列服务器,所以我采用两个 int 和 int[] 并使用 ByteArrayOutputStream
转换它们。 到目前为止,它运行良好,但是由于我从队列中来回传输大量消息,因此我正在尝试压缩我的int[](它有数千个项目,但大多数是零(。 我的想法是将零序列转换为负值(请参阅此问题的答案。
但是我遇到了问题,因为要将我的字节 [] 转换回原始格式,我曾经将 byte[] 的长度除以 4(因为每个 int 的大小为 4,然后循环遍历它(。 由于我在列表中引入了负值,因此大小已更改(每负值 1 个(,这降低了我解压缩数据的能力。 我已经尝试了不同的方法来将数据放入 Byte[] 中,而 ByteArrayOutputStream 似乎是我迄今为止尝试过的最快的方法,所以除非有更快的方法,否则我更喜欢坚持使用这种方法。同样在我的链接问题中,接受的答案有一种方法似乎完全适合我已经用来隐藏数据的现有 for 循环结构(用零序列的负数替换所有零的解决方案(。
任何想法如何区分正/负字节流?
代码如下:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class compressionTest {
public static void main(String[] args) throws IOException {
//to convert to string
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
//data
int data1 = 10;
int data2 = 43;
int[] sub = { 10, 40, 0, 0, 0, 30, 0, 100, 0, 0, 0, 0 }; //should become [10, 40, -3, 30, -1, 100, -4]
//add data to bytes
dos.writeInt(data1);
dos.writeInt(data2);
int count_zero = 0;
for (int j : sub) {
if (j == 0 ) {
//System.out.println("Equals 0!");
count_zero = count_zero + 1;
} else {
if ( count_zero != 0) {
dos.write(-1 * count_zero);
//System.out.println(-1 * count_zero);
count_zero = 0;
}
dos.writeInt(j); //orginally I just had this under the for loop and it works(if you delete the if data above)
}
}
byte[] bytes = baos.toByteArray();
System.out.println(bytes); //this is the data I send
//now bring it back
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
DataInputStream dis = new DataInputStream(bais);
System.out.println("****");
int data1_return = 0;
int data2_return = 0;
System.out.println("size of byte[] is " + bytes.length);
//ArrayList<Integer> sub_return = new ArrayList<Integer>();
int[] sub_return = new int[(bytes.length/4)-2]; //size of data minus first two intgers
for (int item = 0; item<(bytes.length/4);item++){
if (item == 0) {
data1_return = dis.readInt();
} else if (item == 1) {
data2_return = dis.readInt();
} else {
sub_return[item-2] = dis.readInt();
}
}
//print out the data
System.out.println(data1_return);
System.out.println(data2_return);
for (int i : sub_return) {
System.out.println(i);
}
}
}
最简单的方法可能是在开始时对完整列表的大小进行编码,因此,与其使用类似 {0, 1, 2, 3, -5} 的列表,不如使用 {0, 0, 0, 6, 0, 1, 2, 3, -5} -- 然后您只需将前 4 个字节读取为 int,发现它们等于 6, 分配一个 int[6],并将流的其余部分解压缩到其中。