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

我认为它可能是颜色类,所以我使用瞬态修饰符来检查它。还是同样的错误。有任何想法吗?

4

4 回答 4

4

为了实现这一点,我必须:

  • 将所有实现 Serializable 的类重命名为.java,因此DataMatrix变为DataMatrix.java并且Square变为Square.java
  • 在这些类中 使用int而不是color
  • 在这些类中添加缺少的导入

这是代码:

可序列化测试.pde:

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

数据矩阵.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);   

  }
}

文件管理器.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 块中,您的对象的字段依次具有它们的字段,其中一些不实现可序列化...

如果颜色类实现可序列化..?? 如果您正在使用一些不可序列化的第三方库,请尝试基于 xml 的序列化或其他序列化形式,如 json ..

于 2013-06-26T11:58:12.263 回答
1

好吧,我实际上测试了您的代码,但是将未知颜色类更改为一个简单的字符串。它没有抱怨地写了文件,所以,我假设如下:

  1. 也许当您声明瞬态时,您仍然运行旧的编译版本?这取决于您如何设置编译/运行时环境。

  2. 那么颜色类可能会导致问题。您能否准确提供该类的包名以便我们查找它?

  3. 在您的进口中,您是否 100% 确定您是这样进口的?我遇到过这种情况,主要是在 Eclipse 中,当您让 Eclipse 帮助您时,您获取了错误的导入。

    导入 java.io.Serializable;

  4. 你使用的是什么版本的 Java,你在哪里运行你的代码?它看起来像 Applet 的一部分?

根据您的上一个回答,我可以推荐以下内容:

在 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 回答
1

Oracle 本身已经不再强调 Serializable 接口以及 DataInputStream 和 DataOutputStream 类。

这种老式序列化的问题在于,如果您更改对象中需要保存到二进制文件中的字段,那么您现有的文件与新版本的软件不兼容。

我建议您定义自己的文件格式并掌握自己的命运。这需要一点努力,但你不会长期“把自己画到角落里”。

我宁愿使用 XML 文件,也不愿使用 Java 的老式序列化。

或者如果你真的想要一个二进制文件,你可以使用 DataInputStream 和 DataOutputStream 并读写你自己的字段。

但我认为 XML 是最好的,因为生成的文件是“人类可读的”,甚至是“人类可编辑的”。

当我设计文件格式(或要传输的数据的格式)时,我认为最好有一个版本号来标识它是哪个版本的文件格式。您可能不需要此文件格式版本号,但拥有它只会在未来为您提供更大的灵活性。

于 2013-06-28T01:23:10.387 回答