5

ObjectOutputStream の動作に困惑しています。データの書き込み時に9バイトのオーバーヘッドがあるようです。以下のコードを検討してください。

float[] speeds = new float[96];
float[] flows = new float[96];

//.. do some stuff here to fill the arrays with data

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos=null;
try {
    oos = new ObjectOutputStream(baos);
    oos.writeInt(speeds.length);
    for(int i=0;i<speeds.length;i++) {
        oos.writeFloat(speeds[i]);
    }
    for(int i=0;i<flows.length;i++) {
        oos.writeFloat(flows[i]);
    }
    oos.flush();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        if(oos!=null) {
            oos.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

byte[] array = baos.toByteArray();

配列の長さは常に 781 ですが、(1+96+96)*4 = 772 バイトになると予想されます。9バイトがどこにあるのかわかりません。

ありがとう!

-- 編集: NPE を防ぐために if(oos!=null) { ... } を追加

4

4 に答える 4

3

ObjectOutputStreamは、オブジェクトをシリアル化するために使用されます。データがどのように保存されているかを仮定するべきではありません。

生データだけを保存したい場合は、代わりにDataOutputStreamを使用してください。

于 2012-02-27T13:59:51.070 に答える
2

ObjectOutputStream は先頭にヘッダーを書き込みます。

ObjectOutputStream をサブクラス化し、writeStreamHeader() を実装することで、このヘッダーを削除できます。

于 2012-02-27T13:55:17.713 に答える
0

ObjectOutputStream の JavaDoc には次のように記載されています。

シリアライズ可能なフィールドと外部化可能なデータを除くプリミティブ データは、ブロック データ レコードの ObjectOutputStream に書き込まれます。ブロック データ レコードは、ヘッダーとデータで構成されます。ブロック データ ヘッダーは、マーカーとヘッダーに続くバイト数で構成されます。連続するプリミティブ データの書き込みは、1 つのブロック データ レコードにマージされます。ブロック データ レコードに使用されるブロッキング ファクタは 1024 バイトです。各ブロック データ レコードは、最大 1024 バイトまで埋められるか、ブロック データ モードが終了するたびに書き込まれます。ObjectOutputStream メソッドの writeObject、defaultWriteObject、および writeFields を呼び出すと、最初に既存のブロック データ レコードが終了します。

したがって、ブロックしているものは、不足しているオーバーヘッドである可能性があります。

于 2012-02-27T13:58:25.377 に答える
0

Java のシリアライゼーション ストリームは、4 バイトのヘッダー (2 バイトの「マジック ナンバー」の後に 2 バイトのバージョンが続く) で始まります。ヘッダーの後には、一連のブロック データとオブジェクト エントリが続きます。ブロック データ エントリには、「ショート」と「ロング」の 2 種類があります。短いブロックにはブロックごとに 2 バイトのオーバーヘッドがあり、ブロックの長さは最大 255 バイトです。長いブロックには 5 バイトのオーバーヘッドがありますが、最大 4 GB の長さにすることができます。実際に「長い」ブロックの長さは、ObjectOutputStreamの内部バッファのサイズによって異なります。

この場合、長いデータ ブロック エントリは 1 つしかないため、オーバーヘッドはストリーム ヘッダーから 4 バイト、データ ブロックから 5 バイト、合計 9 バイトになります。

ここに完全なドキュメントがあります: http://docs.oracle.com/javase/7/docs/platform/serialization/spec/protocol.html

于 2012-02-27T14:07:21.763 に答える