2011-06-25 14 views
1

から、私はオブジェクトのコレクションを持っている別のシリアル化されたオブジェクトのシリーズを読む:書き込み/に/ファイル

Map<BufferedImage, Map<ImageTransform, Set<Point>>> map 

私は、ファイルにそれらを書き、その後、後ろにそれらを読むことができるようにしたいです同じ構造体。


そのままのBufferedImageはSerializable(もExternalizable)インタフェースを実装していないので、私はちょうど、コレクションを書き込むことはできません。ですから、ImageIOクラスのメソッドを使用して画像を書き込む必要があります。

ImageTransformは、Serializableを実装するカスタムオブジェクトです。だから、は私のマップコレクションの一部であり、そのまま書くことができるはずです。ここで


私は、ファイルに書き込みに何をすべきかです:バックファイルからを読んでここ

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file)); 
    for (BufferedImage image : map.keySet()) { 
     ImageIO.write(image, "PNG", out); // write the image to the stream 
     out.writeObject(map.get(image)); // write the 'value' part of the map 
    } 

は私がに何をすべきかです。しかし

ObjectInputStream in = new ObjectInputStream(new FileInputStream(file)); 
    while(true) { 
     try { 
      BufferedImage image = ImageIO.read(in); 
      Map<ImageTransform, Set<Point>> value = 
       (Map<ImageTransform, Set<Point>>) in.readObject(); // marker 
      map.put(image, value); 
     } catch (IOException ioe) { 
      break; 
     } 
    } 

を、これは機能しません。私はjava.io.OptionalDataExceptionのマーカーにします。

java.io.OptionalDataException 
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1300) 
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:368) 

私の質問は、まず、書き込みのコンセプトは正しいですか?この場合にはImageIO#writeが良いですか?BufferedImage#getRgbint[]アレイを使用/保存することについて考えてください。配列はよりコンパクトです(ファイル内のスペースが少なくなります)。
第2に、オブジェクトをファイルからどのように読み戻す必要がありますか? EOFに達した時期はどうすればわかりますか?なぜ上は動作しないのですか?

私は提供された情報が十分であることを望みます、あなたが何かの詳細情報が必要な場合は教えてください。
ありがとうございます。

答えて

2

ObjectOutputStreamおよびObjectInputStreamは、イメージを順序どおりに書き込まないと違反する特定のファイル形式を書き込み/書き込みするため、機能しません。 ObjectStreamsを正常に使用するには、ObjectStreamsで指定されたコントラクトを監視する必要があります。

これを行うには、保持クラスを作成し、このクラスをBufferedImagesではなくマップのキーとして使用する必要があります。この保持クラスは、Serializableと、クラスを読み取りと書き込みの間に特別な処理が必要であるとマークする3つのメソッド(実際のインターフェイスではない)を実装する必要があります。メソッドのシグネチャは、指定したとおりに指定する必要があります。そうしないと、シリアライズが機能しません。

詳細については、ObjectOutputStreamのdocumentationを参照してください。

public class ImageHolder implements Serializable { 

    BufferedImage image; 

    public ImageHolder(BufferedImage image) { 
     this.image = image; 
    } 

    private void readObject(ObjectInputStream stream) 
      throws IOException, ClassNotFoundException { 
     image = ImageIO.read(stream); 
    } 

    private void writeObject(ObjectOutputStream stream) 
      throws IOException { 
     ImageIO.write(image, "PNG", stream); 
    } 

    private void readObjectNoData() throws ObjectStreamException { 
     // leave image as null 
    } 

次に、逐次編集はoutputStream.writeObject(map)と同じくらい簡単にする必要があります。 ImageTransformの実装クラスもシリアル化可能であることを確認する必要があります。

+0

うん、私はこれを念頭に置いていました。私はこれを見栄えしたいと思っています。私はそれがうまくいけば、それは本当に良い解決策になるには十分なクリーンだと思う。ありがとう。 – c00kiemon5ter

0

「チート」してシリアル化するオブジェクトが1つのみである方法の1つは、オブジェクトのグループを拡張可能な直列化可能リストに追加することです。次に、リストをシリアライズします。

私はXMLEncoderをシリアル化されたオブジェクトよりも使用する傾向があります。これは、後のJVMでリストアできるためです。直列化されたオブジェクトに対する保証はありません。


@Ivan c00kiemon5ter Vカナック:「私は...

、できるだけ小型としてファイルを保存しようとしていることが多いのディスクスペースを考えると、努力を無駄にしています

* ..だから、シリアライゼーションがそれに適していると思います。*

推測しないでください。測定する。

..リストを使ってどのように動くかを試してみます。 ..

クールXMLEncoderを使用している場合は、ほとんどの場合、Zipを使用することをおすすめします。そうすれば、XMLのファイルサイズが小さくなります。この状況は画像を保存する際には異なります。

イメージフォーマットは、通常、Zipによってさらに圧縮されないタイプの圧縮を組み込んでいます。これは、圧縮されたXMLファイルと画像を「生のまま」Zipの別々のエントリに格納することによって、踏み込むことができます。 OTOH私は、XMLだけを圧縮して保存されたバイト数が、画像エントリの最終的なファイルサイズを考えれば、それほど価値はないと思っています。

+0

私はできるだけサイズを小さくしてファイルを保存しようとしています。そのため、シリアライゼーションがより良いと思います。リストを使ってみて、それがどのようになっているかを見てみましょう。ありがとう – c00kiemon5ter

+0

_Don't推測。 Measure._私はそれを期待していました:)私は測定します。私は圧縮システムに取り組んでいるので、スペースを最小限に抑えたいと思っています。だから、私は何が保存されるのか、そうでないのに気をつけなければなりません。私が言ったように、私は 'XMLEncoder'を調べ、いくつかのテストを行い、道に沿っていくつかの新しいことを学びます。 – c00kiemon5ter

+0

'OOSは複数のオブジェクトのEhでうまく動かないのですか? RMIに伝えないでください。もちろんそうです。 ObjectOutputStreamに好きなだけ多くのオブジェクトを書き込み、EOFExceptionが得られるまでそれらを読み戻すことができます。 – EJP

関連する問題