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

时间:2014-09-07 23:51:16

标签: java serialization file-io bytearray fileinputstream

我有一个具有List的对象,每个ObjectA都有一些数据成员(字符串和一个byte [])。随着FileInputStream用于将文件读入字节数组。我已初始化对象的全局范围内的所有数据成员,以便我可以回收它们以减少每个函数调用的对象创建量。当我序列化对象时,我的FileInputStream为null,因为我将文件存储在字节数组中。所以我希望序列化过程会跳过FileInputStream为null。主要对象和放在主对象列表中的对象都实现了可序列化的

只要列表为空,我就能序列化保存对象列表的对象并对其进行反序列化。当列表中至少有一个对象时。它仍然能够序列化,但当我尝试反序列化时,我得到以下错误。

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;
}

为了解决此问题,我将序列化对象保存到文件中并查看它,我可以看到正在保存MainObject。如果我将对象包含在列表中,则还会保存对象。

以下是我为读取文件并将其添加到对象而编写的代码。

   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());
            }   
        }
    }

这是MainObject

中的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 个答案:

答案 0 :(得分:2)

阅读异常消息。与您发布的代码相反,您有一个FileInputStream成员,该成员不可序列化。将其设置为瞬态或删除它,并在需要时从File构建它。

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

注意您新发布的代码:

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语法完成。