【问题标题】:Passing ByteArrayOutputStream into the Constructor of DataOutputStream [closed]将 ByteArrayOutputStream 传递给 DataOutputStream 的构造函数 [关闭]
【发布时间】:2012-12-24 11:43:50
【问题描述】:

我知道这可以使用包装器模式来完成,但我很难理解以下代码是如何工作的。

ByteArrayOutputStream bytearray = new ByteArrayOutputStream();
DataOutputStream os = new DataOutputStream(bytearray);

ByteArrayOutputStream 引用传递给DataOutputStream 的构造函数意味着DataOutputStream 被转换为ByteArrayOutputStream,但是如何?

之后,os.writeUTF("String"); DataOutputStream如何转换为ByteArrayOutputStream

幕后发生了什么?谁能详细解释一下。

【问题讨论】:

标签: java dataoutputstream bytearrayoutputstream


【解决方案1】:

DataOutputStream 只需要在其构造函数中实现OutputStream。它不关心它是如何实现的,只关心它满足接口。 ByteArrayOutputStream 提供由字节数组支持的输出流。同样,您可以使用FileOutputStream 来获取由磁盘上的文件支持的流。从DataOutputStream 的角度来看,它们都是与接口一起使用的流。 OutputStream 是一个非常简单的接口,只是定义了一些将字节数组写入某种存储设备的方法。

幕后没有什么魔法,它只是使用OutputStream,并不关心它是如何实现的。

【讨论】:

  • 感谢您的回答,我了解两者都实现了 OutputStream,但我的问题是 DataOutputStream.write("something") 是如何转换为 ByteArrayOutputStream 的。我正在浏览源代码,当调用 DataOutputStream() 构造函数时,它需要一个 Outputstream 引用,这就是我们正在做的事情,当调用 DataOutputStream.write() 时,在方法中我们看到传入的引用构造函数(在我们的例子中是 bytearray),它实际上调用了这个引用的 write 方法,bytearray.write(),我认为这是它被转换为 ByteArray 的地方。
【解决方案2】:

其实这可以称为装饰器模式。 DataOutputStream 采用任何现有的 OutputStream(在我们的例子中为 ByteArrayOutputStream)并将对它的引用存储在

protected OutputStream out;

(其实DataOutputStream在java.io.FilterOutputStream中扩展)。

现在让我们看看 DataOutputStream.writeInt 是如何工作的(writeUTF 太重了)

public final void writeInt(int v) throws IOException {
    out.write((v >>> 24) & 0xFF);
    out.write((v >>> 16) & 0xFF);
    out.write((v >>>  8) & 0xFF);
    out.write((v >>>  0) & 0xFF);
...

它只需要一个 int arg 并使用常规的 OutputStream.write(byte) 逐字节写入它的 4 个字节。在我们的例子中,这些字节将被写入 ByteArrayOutputStream 内部字节数组。如果可以将 ByteArryOutputStream 更改为 FileOuputStream 并将数据写入文件,则 DataOutuputStream 不需要了解实际实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-20
    • 2019-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-07
    • 2011-09-24
    相关资源
    最近更新 更多