2

奇妙な問題があります。基本的に、入力を byte[] としてのみ受け取るキュー サーバーを使用しているため、2 つの int と int[] を取得し、 を使用して変換していByteArrayOutputStreamます。これまでのところ問題なく動作していますが、キューとの間で多くのメッセージをやり取りしているため、int [] を圧縮しようとしています (数千のアイテムがありますが、大部分はゼロです)。一連のゼロを取り、それらを負の値に変換するというアイデアを得ました (この質問への回答を参照してください.

しかし、バイト[]を元の形式に変換するために、バイト[]の長さを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);
        }

    }

}
4

1 に答える 1

0

最も簡単な方法は、おそらく最初に完全なリストのサイズをエンコードすることです。したがって、{0、1、2、3、-5}のようなリストを作成する代わりに、{0、0、0、6、0}を作成します。 、1、2、3、-5}-次に、最初の4バイトをintとして読み取り、それらが6に等しいことを確認し、int [6]を割り当て、残りのストリームをそれに解凍します。

于 2012-04-29T17:06:24.433 に答える