从文件中读取对象不起作用.dat



我在从文件中读取对象时遇到问题。当我试图从.dat文件中读取对象时,它只打印第一个对象。然后将出现一条错误消息'java.io.StreamCorruptedException:无效类型代码:AC'。我的代码出了什么问题?我试图找到一个解决方案,但没有成功。每个对象都被单独保存到文件中(我在GUI中有保存按钮(。

我的对象保存方法,哪个参数是对象:

public static void saveObject(GymDiary object){
try (ObjectOutputStream dataOut = new ObjectOutputStream(new FileOutputStream("objectFile.dat", true))){
dataOut.writeObject(object);
dataOut.flush();
dataOut.close();
System.out.println("saving succeeded!");
} catch (IOException e) {
e.printStackTrace();
}
} 

我的对象读取方法:

public static void readObjects() throws  IOException {
ArrayList<gymDiary> objectList = new ArrayList<>();
boolean endOfFile= true;
int x = 0;

try (ObjectInputStream objectFile = new ObjectInputStream(new FileInputStream("objectFile.dat"))) {
while (endOfFile) {
gymDiary object = null;
try {
object = (GymDiary) objectFile.readObject();
objectList.add(object);
} catch (ClassNotFoundException e){
e.printStackTrace();
}
if (object != null) {
System.out.println(objectList.get(x).getLoad());
x++;
} else {
endOfFile= false;
objectFile.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

错误加入行:object=(GymDiary(objectFile.readObject((

我保存对象的方法有问题吗?还是我的储蓄方法有问题?或者两者都有?:D

我的目标是打印文件中的所有对象。不仅仅是第一个。

.dat文件看起来像这样,有两个对象(有些东西是我母语的,不要介意(:

¬í sr *com.example.work.gymDiaryËQj$b8ˆ L kuormatt Ljava/util/ArrayList;L 
liikeNimetq ~ L toistotq ~ L treeninNimit Ljava/lang/String;xpsr java.util.ArrayListxÒ™Ça I sizexp   w   sr java.lang.Double€³ÂJ)kû D valuexr java.lang.Number†¬•”à‹  xp@I      sq ~ @I      sq ~ @I      xsq ~    w   t squatxsq ~    w   sr java.lang.Integerâ ¤÷‡8 I valuexq ~    q ~ q ~ xt legday¬í sr *com.example.work.gymDiaryËQj$b8ˆ L kuormatt Ljava/util/ArrayList;L 
liikeNimetq ~ L toistotq ~ L treeninNimit Ljava/lang/String;xpsr java.util.ArrayListxÒ™Ça I sizexp   w   sr java.lang.Double€³ÂJ)kû D valuexr java.lang.Number†¬•”à‹  xp@I      sq ~ @I      sq ~ @I      xsq ~    w   t 
benchpressxsq ~    w   sr java.lang.Integerâ ¤÷‡8 I valuexq ~    q ~ q ~ xt upperbodyday

这里的问题很可能是序列化和反序列化方法的行为不同。序列化代码总是创建一个新的ObjectOutputStream,然后将数据附加到文件中。这将每次写入流头(magic&version(。但是,反序列化方法只创建一次ObjectInputStream,因此也只使用流头一次。因此,您必须:

  • 使用单个ObjectOutputStream写入所有对象
  • 或者使用单独的新ObjectInputStream读取每个对象

此外,检测文件结尾的逻辑可能有缺陷(除非您遗漏了代码(。当流中没有其他对象时,readObject()会抛出一个异常(当前为EOFException,但文档不保证会出现此特定异常(。因此,您应该显式调用writeObject(null);那么您可以检测CCD_ 8何时返回CCD_。


考虑Java序列化的替代方案可能也很好,因为在某些情况下,它的效率不是很高,对于不受信任的数据,它可能非常危险,在最坏的情况下会导致远程代码执行(针对这种情况的保护措施冗长且容易出错(。另请参阅Java SE.的安全编码指南

最新更新