ファイルからオブジェクトをデシリアライズし、それらのいくつかだけを同じファイルにシリアライズすることは可能ですか? もちろん、前後のオブジェクトの数は同じでなければなりません。新しいオブジェクトをファイルに追加したくありませんが、変更されたオブジェクトを上書きします。たとえば、ファイル「file.ser」から取得した約 1000 個のオブジェクトがあります。それらを逆シリアル化し、3 つだけ変更して、これらを同じファイルに上書きしたいと考えています。出来ますか?
3 に答える
短い答えはノーです。変更されたオブジェクトをファイル内の「インプレース」で上書きすることはできません。
を作成するObjectOutputStream
と、オブジェクトを書き込む前であっても、ストリームはいくつかのマジック ナンバー マーカー バイトを基になるストリームに書き込みます。これらのバイトは、ObjectInputStream
作成時に によって自動的に消費されます。これはストリーム ヘッダーです。
さらに、 を使用してオブジェクトを作成する場合、そのObjectOutputStream.writeObject()
オブジェクトを単純にシリアル化して分離しているわけではありません。ストリームは、以前にシリアル化したオブジェクト参照を追跡し ( を呼び出さない限り)、オブジェクトを完全に書き出す代わりに、実際のオブジェクトが書き込まれた場所を指すハンドルを書き込みます。reset()
最後に、ストリームに書き込まれるオブジェクト間にブロック アラインメントやパディングはありません。オブジェクトは連続して書き込まれます。
これはすべて、オブジェクトを変更した場合、行った構造上の変更 (別のオブジェクトへの参照など) によって、ハンドルが異なり、オブジェクトの長さが異なる可能性があることを意味します。ブロックのアライメントが発生しないため、オブジェクトを同じ場所に書き戻すことはできません。これは、行った変更が長さに影響を与える可能性が高く、同じではないためです。別のオブジェクトの上部。
いいえ、ファイルを再作成する必要があります。オブジェクト ストリームは、単なるレコードのセットではなく、実際にはストリームです。
速度が気になる場合は、Java が非常に高速であることが常にわかっています。全体を読んでもあまりペナルティはないかもしれません - いくつかのプロファイリングを試してください。
Java Serialization を Google Protocol Buffers などの代替手段に置き換えることができます。
ProtoBuf は非常に高速で、スペース効率が非常に優れています。