3

処理で色付きの正方形の 3D マトリックスを作成しようとしています。正常に動作しますが、DataMatrix オブジェクトをシリアル化するファイルに保存しようとすると、java.io.NotSerializableException という例外が発生します。Square と DataMatrix の両方が Serializable を実装しているため、何が原因なのかわかりません。

ファイルマネージャー:

class FileManager
{

  FileManager()
  {}

  public void saveMatrix(String path, DataMatrix dm)
  {
    try
    {
    FileOutputStream file = new FileOutputStream(path);
    ObjectOutputStream output = new ObjectOutputStream(file);
    output.writeObject(dm); 
    output.close();
    }
    catch (Exception e)
    {
       e.printStackTrace();
    }
  } 

  public DataMatrix openMatrix(String path)
  {
    DataMatrix dm = null;

    try
    {

       FileInputStream file = new FileInputStream(path);
       ObjectInputStream input = new ObjectInputStream(file);
       Object aux = input.readObject();
       input.close();
       if(aux instanceof DataMatrix)
       {
         dm = (DataMatrix)aux;
       }        
    }
    catch (EOFException e1)
    {
       System.out.println ("Fin de fichero");
    }
    catch (Exception e2)
    {
        e2.printStackTrace();
    }

    return dm; 
  }
}

データマトリックス:

class DataMatrix implements Serializable
{

  Square[][][] dataMatrix;

  DataMatrix()
  { 
      dataMatrix = new Square[5][32][32];
  }

  public void setSquare(int x, int y, int z, color c, String type)
  {

     dataMatrix[z][x][y].setSquare(c,type);   

  }

四角:

class Square implements Serializable
{

  public int x;
  public int y;
  public int z;
  public color c;
  public String type;

  Square(int xx, int yy, int zz, color cc, String tt){
    x = xx;
    y = yy;
    z = zz;
    c = cc;
    type = tt; 
  }

  public void setSquare(color cc, String tt){

    c = cc;
    type = tt;

  }

  public void printSquare()
  {
     println(green(c) +"  "+ type); 
  }

}

エラーログ:

java.io.NotSerializableException: processing.core.PApplet$InternalEventQueue
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
    at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
    at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
    at maindatamatrix$FileManager.saveMatrix(maindatamatrix.java:105)
    at maindatamatrix.setup(maindatamatrix.java:30)
    at processing.core.PApplet.handleDraw(PApplet.java:2245)
    at processing.core.PGraphicsJava2D.requestDraw(PGraphicsJava2D.java:243)
    at processing.core.PApplet.run(PApplet.java:2141)
    at java.lang.Thread.run(Thread.java:662)
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: processing.core.PApplet$InternalEventQueue
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1332)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1666)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1322)
    at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1666)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1322)
    at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1666)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1322)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    at maindatamatrix$FileManager.openMatrix(maindatamatrix.java:123)
    at maindatamatrix.setup(maindatamatrix.java:33)
    at processing.core.PApplet.handleDraw(PApplet.java:2245)
    at processing.core.PGraphicsJava2D.requestDraw(PGraphicsJava2D.java:243)
    at processing.core.PApplet.run(PApplet.java:2141)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.io.NotSerializableException: processing.core.PApplet$InternalEventQueue
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
    at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
    at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
    at maindatamatrix$FileManager.saveMatrix(maindatamatrix.java:105)
    at maindatamatrix.setup(maindatamatrix.java:30)
    ... 4 more

色のクラスかもしれないと思ったので、transient 修飾子を使用して確認しました。それでも同じエラーです。何か案は?

4

4 に答える 4

4

これを達成するには、次のことを行う必要がありました。

  • Serializable を実装するすべてのクラスの名前を.javaに変更します。したがって、DataMatrixDataMatrix.javaになり、SquareSquare.javaになります。
  • これらのクラス intの代わりに使用color
  • これらのクラスに不足しているインポートを追加します

コードは次のとおりです。

SerializableTest.pde:

void setup(){
  DataMatrix dm = new DataMatrix();
  FileManager f = new FileManager();
  f.saveMatrix("/Users/me/test", dm);
}

DataMatrix.java:

import java.io.Serializable;

class DataMatrix implements Serializable
{

  Square[][][] dataMatrix;

  DataMatrix()
  { 
      dataMatrix = new Square[5][32][32];
  }

  public void setSquare(int x, int y, int z, int c, String type)
  {

     dataMatrix[z][x][y].setSquare(c,type);   

  }
}

FileManager.pde:

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.EOFException;

class FileManager
{

  FileManager()
  {}

  public void saveMatrix(String path, DataMatrix dm)
  {
    try
    {
    FileOutputStream file = new FileOutputStream(path);
    ObjectOutputStream output = new ObjectOutputStream(file);
    output.writeObject(dm); 
    output.close();
    }
    catch (Exception e)
    {
       e.printStackTrace();
    }
  } 

  public DataMatrix openMatrix(String path)
  {
    DataMatrix dm = null;

    try
    {

       FileInputStream file = new FileInputStream(path);
       ObjectInputStream input = new ObjectInputStream(file);
       Object aux = input.readObject();
       input.close();
       if(aux instanceof DataMatrix)
       {
         dm = (DataMatrix)aux;
       }        
    }
    catch (EOFException e1)
    {
       System.out.println ("Fin de fichero");
    }
    catch (Exception e2)
    {
        e2.printStackTrace();
    }

    return dm; 
  }
}

Square.java:

import java.io.Serializable;
import processing.core.*;

class Square implements Serializable
{

  public int x;
  public int y;
  public int z;
  public int c;
  public String type;

  Square(int xx, int yy, int zz, int cc, String tt){
    x = xx;
    y = yy;
    z = zz;
    c = cc;
    type = tt; 
  }

  public void setSquare(int cc, String tt){

    c = cc;
    type = tt;

  }

  public void printSquare()
  {
     //System.out.println(PApplet.green(c) +"  "+ type);
    int g = (c >> 8) & 0xFF;   // Faster way of getting green(argb)
    System.out.println(g); 
  }

}
于 2013-06-27T11:01:24.380 に答える
2

ファイルマネージャークラスでは、tryブロック内にあるようですオブジェクトのフィールドには、順番にフィールドがあり、そのうちのいくつかはSerializableを実装していません...

color クラスが serializable を実装している場合..?? シリアライズできないサードパーティのライブラリを使用している場合は、xml ベースのシリアライゼーションまたは json などのシリアライゼーション フォームを試してください。

于 2013-06-26T11:58:12.263 に答える
1

Oracle 自体は、Serializable インターフェイスと DataInputStream および DataOutputStream クラスを軽視しています。

この昔ながらの種類のシリアル化の問題は、バイナリ ファイルに保存する必要があるオブジェクトのフィールドを変更すると、既存のファイルがソフトウェアの新しいバージョンと互換性がなくなることです。

独自のファイル形式を定義し、独自の運命を管理することをお勧めします。前もって少し努力する必要がありますが、長期的には「追い詰められる」ことはありません。

私は、Java の昔ながらのシリアル化よりも XML ファイルを使用したいと考えています。

または、本当にバイナリ ファイルが必要な場合は、DataInputStream と DataOutputStream を使用して、独自のフィールドを読み書きできます。

しかし、結果として得られるファイルは「人間が読める」、さらには「人間が編集できる」ため、XML が最適だと思います。

ファイル形式 (または送信されるデータの形式) を設計するとき、それがファイル形式のどのバージョンであるかを識別するバージョン番号を持つことは良い考えだと思います。このファイル形式のバージョン番号は必要ないかもしれませんが、あると将来の柔軟性が高まります。

于 2013-06-28T01:23:10.387 に答える
1

さて、私は実際にあなたのコードをテストしましたが、未知のカラー クラスを単純な文字列に変更しました。文句なしにファイルを書き込んだので、次のように仮定します。

  1. 一時的と宣言したとき、コンパイル済みの古いバージョンをまだ実行していたのでしょうか。これは、コンパイル/ランタイム環境のセットアップ方法によって発生する可能性があります。

  2. 色クラスが問題を引き起こしている可能性があります。検索できるように、そのクラスのパッケージ名を正確に教えていただけますか?

  3. あなたのインポートでは、このようにインポートしていると 100% 確信していますか? 私は、主にEclipseで、Eclipseに助けてもらったときに間違ったインポートを取得することがありました。

    java.io.Serializable をインポートします。

  4. 使用している Java のバージョンと、コードを実行している場所は? アプレットの一部のように見えますか?

最後の回答によると、次のことをお勧めします。

Square クラスに 3 つの変数を格納します。

private int r;
private int g;
private int b;

public void setColor(int r, int g, int b) {
    this.r = r;
    this.g = g;
    this.b = b;
}

public color getColor() {
    return color(r, g, b);
}

このようにして、色のシリアル化の問題を取り除きます。

ところで、私はあなたが処理によってこれを意味していると仮定しています: http://processing.org

于 2013-06-26T12:17:54.390 に答える