3

私はJavaクラスを持っています

public class MsgLayout{
int field1;
String field2;
long field3;
}

このオブジェクトをSocket出力ストリームのバイト配列として書き込む必要があります。3つのフィールド(インスタンス変数)にはレイアウトがあります。つまりfield1、1バイトをfield2占有し、4バイトを占有し、 field38バイトを占有する必要があります。

ByteBuffer bbf = ByteBuffer.allocate(TOTAL_SIZE);
bbf.put(Integer.toString(this.getField1()).getBytes(), 0, FIELD1_SIZE);
bbf.position(FIELD2_OFFSET);
bbf.put(Long.toString(this.getField2()).getBytes(), 0, FIELD2_SIZE);
bbf.position(FIELD3_OFFSET);
bbf.put(Long.toString(this.getField3()).getBytes(), 0, FIELD3_SIZE);
byte[] msg = bbf.array();

上記のコードを使用して、バイト配列の各フィールドを目的のサイズに合わせて調整しようとしています。しかしIndexOutOfBoundException 、要するに、問題は、フィールドをレイアウトで定義されたサイズに合わせる方法に関するものです。たとえば、StringFIELD1_OFFSET = 0, FIELD1_SIZE=1, FIELD2_OFFSET=1, FIELD2_SIZE=4, FIELD3_OFFSET=5, FIELD3_SIZE=8. に変換するとfield1、byte[]に変換すると1バイトに収まりません。Stringに変換せず、putInt(int)を使用すると、結果のバイト配列に4バイトが書き込まれます。

4

2 に答える 2

2

コードが現在行っていることは、数値フィールドを文字列としてエンコードし、それらの文字のバイトを出力することです。

DataOutputStream クラスを使用して SocketOutput ストリームをラップし、バイナリ データを次のように書き込むことをお勧めします。

DataOutput output = new DataOutputStream(socketOutputStream);

int field1 = 1;
String field2 = "Hello";
long field3 = 5000000000L;

output.writeByte(field1);
output.writeBytes(field2.substring(0, 3));
output.writeLong(field3);

このコードにはいくつかの仮定があります。まず、フィールド 2 では、4 文字をそれぞれ 1 バイトとしてシリアル化する必要があると想定しています。UTF-8 などを使用してマルチバイト エンコーディングを行いたい場合は、少し異なる方法で行う必要があります。次に、フィールド 2 には常に少なくとも 4 文字が含まれると想定しています。

于 2011-09-28T14:52:06.250 に答える
0

field1データは 1 バイトしかありませんが、その文字列表現は 1 つ以上の文字になります (例: , "0") 。String 内の各文字は、実際には a (2 バイト値) です。したがって、byte->String->byte[] 変換を行うと、1 バイトのデータが 2 ~ 6 バイトのデータに膨らむことが予想されます。"63""127"char

于 2011-09-28T14:48:26.157 に答える