2012-04-29 10 views
3

私は奇妙な問題があります。私は2つのintとint []をとり、ByteArrayOutputStreamを使ってそれらを変換するので、基本的に私はバイト[]としてだけ入力を取るキューサーバーを使用しています。これまでは問題なく動作していましたが、キューから前後にたくさんのメッセージを転送しているので、私はint []を圧縮しようとしています(数千項目ありますが、大半はゼロです)。私は0のシーケンスを取って負の値にする考えを持っていました。(questionbyte []から変換された負の値を持つintをどのように識別できますか?

私のバイト[]を元のフォーマットに戻すために問題があります。 (つまり、各intは4の大きさでループしているので、これを4で割った値になります)リストに負の値を導入しているので、サイズは負の値で1ずつ変化しています。 Byte []に​​データを取得するさまざまな方法を試しましたが、ByteArrayOutputStreamはこれまでに試した中で最も速いと思われます。何か速いものがなければ、このメソッドを使うことをお勧めします。私のリンクされた質問では、受け入れられた答えは、私がすでに秘密のデータ(すべてのzeを置き換えるソリューションroのゼロのシーケンスの負の数)。

どのように私は肯定/否定のバイトのストリームを区別することができます任意のアイデアですか?

ここでは、コードは次のとおり

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

これらは正および負のバイトではなく、intです。したがって、4バイトを整数にグループ化する必要があります。次に、整数が負か正かどうかを確認できます。さらに、整数が負の場合、4つの整数のうちの最初の整数は、リトルエンディアンでは負、ビッグエンディアンの場合は最後になります。重要な発言は、テーリングゼロが受信者に送信されないので、アルゴリズムが機能しないことです! –

答えて

0

最も簡単な方法は、これに代えてのようなものだリストを有する開始時に完全なリストのサイズを符号化するためにおそらく{0、1、2、3、 - 5}あなたは{0、0、0、6、0、1、2、3、-5}を持っています - ちょうどintとして最初の4バイトを読み、それらが6に等しいことを見いだし、 [6]、残りのストリームをそのストリームに解凍します。

+0

なぜ「new int [5]」の代わりにint [6]を割り当てるのですか?私はサイズが間違っていると思うので、 'int [6]'はJavaの型ではありません。 –

+0

元の質問を誤解していない限り、私が提供したリストは0x00010203に6回バイトシーケンス0,1,2,3のために1回、そしてこれは-5のためにさらに5回繰り返される)。次に 'int [6]'を割り当てることによって、結果を格納する配列を作成するために 'new int [6]'を使用することを意味します。 – Jules

関連する問題