java - 为什么同时声明读写资源会抛出异常?

标签 java serialization

我正在尝试序列化并编写了以下类:

public static void main(String[] args) throws ClassNotFoundException{
    File file = new File("D:/serializable.txt");
    try(FileOutputStream fos = new FileOutputStream(file);
            ObjectOutputStream ous = new ObjectOutputStream(fos);
          FileInputStream fis = new FileInputStream(file);
          ObjectInputStream ois = new ObjectInputStream(fis)){
//      SerialTest st = new SerialTest();
//      ous.writeObject(st);
        SerialTest st = (SerialTest) ois.readObject();
        System.out.println(st);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

序列化类:

public static class SerialTest implements Serializable{

    private int count;

    private Object object;

    public int count(){
        return count;
    }

    public Object object(){
        return object;
    }

    private void readObject(ObjectOutputStream ous) throws IOException{
        ous.writeObject(object);
        ous.writeInt(count);
    }

    private void writeObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{
        ois.readInt();
        ois.readObject();
    }
}

按照commeted代码中的方式序列化对象后,我尝试按照此处指定的方式对其进行反序列化。我得到了

java.io.EOFException
    at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2598)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1318)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)

此外,包含序列化对象的文件的内容被更改。

但是当我删除资源声明时

FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream ous = new ObjectOutputStream(fos);

从 try-with-resources 子句来看,它工作得很好。为什么?为什么资源声明会影响反序列化?

最佳答案

如果没有 write 调用,您当前将创建一个 文件,因为这就是您调用的 FileOutputStream 构造函数的作用。如果文件已存在,则将其截断为 0 字节长。因此,当您尝试从中读取对象时,将无法读取任何内容。

即使写入部分未注释,仍然可能出现缓冲问题,即数据尚未实际写入文件。

我强烈建议您编写该文件并关闭输出流,然后单独打开它以进行输入。对我来说,同时打开同一个文件进行读取和写入似乎会导致结果困惑。

所以代码看起来像这样:

// Exception handling omitted as this is just test code
public static void main(String[] args) throws Exception {
    File file = new File("D:/serializable.txt");
    try (FileOutputStream fos = new FileOutputStream(file);
         ObjectOutputStream ous = new ObjectOutputStream(fos)) {
        SerialTest st = new SerialTest();
        ous.writeObject(st);
    }
    try (FileInputStream fis = new FileInputStream(file);
         ObjectInputStream ois = new ObjectInputStream(fis)) { 
        SerialTest st = (SerialTest) ois.readObject();
        System.out.println(st);
    }
}

关于java - 为什么同时声明读写资源会抛出异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34172592/

相关文章:

JavaCC 问题 - 生成的代码没有找到所有解析错误

java - 我应该使用 hibernate 二级缓存吗?

c# - XML - 将属性反序列化为 Xml 子树

java - 反序列化后锁的状态是什么

java - 在存在序列化的情况下理解 Java 内存模型下的一个棘手案例

java - 计算两个位置之间的像素距离

java - 过滤掉 CompletableFuture 的重复项

java - 使用 Collectors 将 Steam 拆分为基于 Java 类的列表

java - 在自定义序列化程序 jackson 中配置 objectmapper?

serialization - 使用 Doctrine MongoDB ODM 进行文档序列化