有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

序列化Java serialize List<object>每个对象在字节数组中保存一个文件

我有一个对象,它有一个列表,每个对象都有几个数据成员(字符串和一个字节[])。以及用于将文件读入字节数组的FileInputStream。我已经初始化了对象全局范围内的所有数据成员,以便可以循环使用它们,以减少每次函数调用创建对象的次数。当我序列化对象时,我的FileInputStream为空,因为我将文件存储在字节数组中。因此,我预计序列化过程将跳过为null的FileInputStream。主对象和放在主对象列表中的对象都实现了可序列化

我可以序列化包含对象列表的对象,只要列表为空,就可以反序列化它。当列表中至少有一个对象时。它仍然可以序列化,但当我试图反序列化它时,我得到了以下错误

IOException: writing aborted; java.io.NotSerializableException: java.io.FileInputStream

我的对象中的变量如下所示:

public class MainObject implements Serializable{
     private String name;
     private List<ObjectA> obj;
}

public class ObjectA implements Serializable{
         private String id;
         private String name;
         private File fileStream;
         byte []data;
}

为了解决这个问题,我将序列化对象保存到一个文件中,并查看它,我可以看到main对象正在被保存。如果我将对象包括在列表中,对象也会被保存

下面是我用来读取文件并将其添加到对象的代码

   File[] files = new File(filePath).listFiles();
    for (File file : files) {
        if (file.isFile()) {
            System.out.println(file.getName());
            try {
                fin = new FileInputStream(filePath+file.getName());
                ois = new ObjectInputStream(fin);
                mainObjectList.add((MainObject) ois.readObject());
                ois.close();
                fin.close();
            } catch (FileNotFoundException e) {
                 System.err.println("FileNotFoundException: " + e.getMessage());
            } catch (ClassNotFoundException e) {
                 System.err.println("ClassNotFoundException: " + e.getMessage());
            } catch (IOException e) {
                 System.err.println("IOException: " + e.getMessage());
            }   
        }
    }

这是main对象中的setFile()

   public void setFile(String filePath) {
        try {
            File file=null;
            fileStream = new FileInputStream(file=new File(filePath));
            data = new byte[(int)file.length()];
            fileStream.read(data,0,data.length);
            for (int X : data){
                System.out.print((char)X);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }

    } 

共 (1) 个答案

  1. # 1 楼答案

    阅读异常消息。与您发布的代码相反,您有一个FileInputStream成员,它是不可序列化的。使其成为暂时的,或者删除它,并在需要时从File中构造它

    与你声称的“当我序列化mainObject并将其保存到文件中时,我可以看到它保存了所有数据,包括音频剪辑对象列表”相反,当你序列化这些数据时,你得到了一个异常,你忽略了它

    注意:您新发布的代码:

    try {
            File file=null;
            fileStream = new FileInputStream(file=new File(filePath));
            data = new byte[(int)file.length()];
            fileStream.read(data,0,data.length);
            for (int X : data){
                System.out.print((char)X);
            }
    
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }
    

    质量很差。应该这样写:

    try (FileInputStream fileStream = new FileInputStream(new File(filePath))) {
        data = new byte[(int)file.length()];
        int total = 0;
        int count;
        while ((count = fileStream.read(data, total, data.length-total)) > 0) {
            total += count;
        }
        for (byte X : data) {
            System.out.print((char)X);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }catch (IOException e) {
        e.printStackTrace();
    }
    

    请注意,您不能假设文件适合内存、大小适合int,read()填充缓冲区。你必须:

    • read()的结果存储到变量中
    • 测试-1,表示流结束
    • 否则,将其用作读取计数,而不是缓冲区大小
    • 重复上述步骤,直到流程结束

    还要注意,您根本不需要File file变量;FileInputStream应该一直是一个局部变量;您没有关闭它:这段代码通过try with resources语法关闭了它