java - JAVA中flush()和reset()的区别

标签 java io reset flush

我只是想知道 flush 和 reset 之间的区别是什么? 为什么在 example 中刷新后使用重置? flush方法删除内存缓存为什么要用reset方法?

ObjectOutputStream oos = new ObjectOutputStream(bos);

while(true){
    oos.writeObject(object);
    oos.flush();
    oos.reset();

    object.x++;
}

最佳答案

Why is reset method used if memory cache is wiped by flush method?

flush() 将在底层 OutputStream 中写入 ObjectOutputStream 对象的缓冲区,但它不会重置 的整个状态code>ObjectOutputStream 对象。

如果打开ObjectOutputStream源代码类,您可以看到在缓冲区之外它包含许多实例字段。
这是一个小片段:

/** filter stream for handling block data conversion */
private final BlockDataOutputStream bout;
/** obj -> wire handle map */
private final HandleTable handles;
/** obj -> replacement obj map */
private final ReplaceTable subs;
/** recursion depth */
private int depth;
/** buffer for writing primitive field values */
private byte[] primVals;

一些处理转换,另一些处理缓存,等等... ObjectOutputStream.reset() 将对此状态产生影响:

Reset will disregard the state of any objects already written to the stream.

Objects previously written to the stream will not be referred to as already being in the stream. They will be written to the stream again.

这些细节很重要,因为 ObjectOutputStream 使用引用共享机制。
所以在流中多次写入同一个对象但具有不同的状态将多次写入具有原始状态的对象。
The top level documentation of ObjectOutputStream解释更多(重点是我的):

The default serialization mechanism for an object writes the class of the object, the class signature, and the values of all non-transient and non-static fields. References to other objects (except in transient or static fields) cause those objects to be written also. Multiple references to a single object are encoded using a reference sharing mechanism so that graphs of objects can be restored to the same shape as when the original was written.

你现在应该明白reset()的意思了。


说明 ObjectOutputStream 缓存问题的示例:

执行此类,在 ObjectOutputStream 中写入 10 次相同对象但状态不同,而无需在写入之间调用 reset():

public class FlushAndReset {

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);

        Foo foo = new Foo();
        for (int i = 0; i < 10; i++) {
            foo.setValue(i);
            oos.writeObject(foo);
            oos.flush();
            // oos.reset();
        }

        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
        for (int i = 0; i < 10; i++) {
            Object obj = ois.readObject();
            System.out.println(obj);
        }
    }
}

Foo 定义为:

public class Foo implements Serializable {

    private int value;

    public void setValue(int value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Foo [value=" + value + "]";
    }

}

当您阅读 BOS 的内容时,您将获得:

Foo [value=0]

Foo [value=0]

Foo [value=0]

Foo [value=0]

Foo [value=0]

Foo [value=0]

Foo [value=0]

Foo [value=0]

Foo [value=0]

Foo [value=0]

取消对 reset() 的注释,您应该会看到更改:

Foo [value=0]

Foo [value=1]

Foo [value=2]

Foo [value=3]

Foo [value=4]

Foo [value=5]

Foo [value=6]

Foo [value=7]

Foo [value=8]

Foo [value=9]

关于java - JAVA中flush()和reset()的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51115157/

相关文章:

java - OriginalDestination 可以用作死信队列使用者的选择器吗?

c - 通过探测从缓冲区写入文件,C 程序

java - InputStream 当部分名称已知时? (安卓)

email - Laravel 5.1 重置密码功能;用户的电子邮件在不同的表中

Jquery 父兄弟重置 css

java - 是否可以在变量访问/写入时停止 Debug模式的执行?

java - Java Application Server有哪些Web服务器无法做到的具体用途?

java - 从 Java 文本文件中的字符串中查找数字

c - 制作自定义 tr.c 函数

python - Django 密码重置表单