将OutputStream转换为ByteArrayOutputStream

18
我正在尝试将OutputStream转换为ByteArrayOutputStream。我找不到任何清晰简单的答案来解决这个问题。这个问题在StackOverflow的标题中被问到,但问题的正文询问如何将ByteArrayStream更改为OuputStream。我已经创建了一个OutputStream,而且答案中给出的示例无法编译! 该问题在此处 我有一个已经构造好并且长度为44个字节的OutputStream,名为waveHeader。我想将其转换为ByteArrayOutputStream,因为我想在以后的过程中通过waveHeader.ToByteArray()将其更改为byte[]以便于简化处理。
是否有一种简单的类型转换或其他方法可以实现这一点?
如果不行,那么:
- 如果不可能将其转换,是否有一种构造指向原始OutputStream数据的指针的方法? - 如何访问OutputStream中包含的数据?

我是JAVA的新手。这只是我的业余爱好。在VisualBasic.net中,流程要简单得多!


1
我认为没有必要发布任何代码。 - Bill Smith
不清楚的答案!请阅读整个问题。那个例子无法编译! - Bill Smith
1
写入那44个字节的代码必须首先写入您的ByteArrayOutputStream。该代码不知道它正在写入BAOS,只要依赖于OS类即可。 - eckes
1
你无法将任意的 OutputStream 转换为 ByteArrayOutputStream,但是你可以更改提供原始 OutputStream 的代码,以便提供一个 ByteArrayOutputStream - Louis Wasserman
那段代码要改起来很麻烦。 - Bill Smith
为什么这个问题被踩了? - Bill Smith
3个回答

27

有多种可能的情况:

a)您有一个ByteArrayOutputStream,但它被声明为OutputStream。然后您可以这样进行强制类型转换:

void doSomething(OutputStream os)
{
    // fails with ClassCastException if it is not a BOS
    ByteArrayOutputStream bos = (ByteArrayOutputStream)os;
...

b) 如果您有任何其他类型的输出流,将其转换为BOS并没有什么意义。(通常希望进行类型转换,因为希望访问结果数组)。所以在这种情况下,您只需设置一个新流并使用它。

void doSomething(OutputStream os)
{
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    bos.write(something);
    bos.close();
    byte[] arr = bos.toByteArray();
    // what do you want to do?
    os.write(arr); // or: bos.writeTo(os);
...

c) 如果您已向任何类型的OutputStream(例如,因为您从Servlet中获取了它而不知道它是什么)写入了某些内容,则无法将该信息取回。您不应编写需要稍后使用的内容。解决方案是答案b),在其中将其编写到您自己的流中,然后您可以将该数组用于自己的目的以及将其写入实际输出流。

请记住ByteArrayOutputStream会在内存中保留所有数据。


嗯...关于Java的流(streams)有些东西我就是不理解。为什么有OutputStream(它是唯一可被写入的类型),却不能访问其中的数据呢?它们永远不应该被用作变量来保存任何稍后要输出的数据吗?我正在处理一个音频项目,大多数东西似乎都在以某种方式使用OutputStreams。我在Android API中找到了一些代码,它创建了一个波形文件头,只是一个OutputStream。 - Bill Smith
经过思考,我猜想你可以附加OutputStreams来构造最终要传输到InputStream的数据?我会阅读有关Streams及其正确使用方法的资料。 - Bill Smith
是的,一旦你将数据存储在数组中,你可以轻松地再次使用它:InputStream is = new ByteArrayInputStream(bos.toByteArray()); - eckes
OutputStream是您想要写入时“某人”呈现的类型。无论对数据进行了什么操作,您都会使用它。如果它写入套接字、文件、内存、servlet响应,您都不需要关心,您始终在OS上使用write()方法。调用您的人负责设置流,使数据流向某个地方或(在BOS的情况下)可以从中检索数据。直接编写(“流式传输”)是首选,因为它不会引入内存使用或延迟。 - eckes
OutputStream$1 无法转换为 java.io.ByteArrayOutputStream。 - aswzen
@aswzen,a)点从前提开始,如果这个前提不成立,你就不能使用替代方案,这就是为什么它包含多个选项的原因。 - eckes

5
你可以使用ByteArrayOutputStreamwriteTo方法。
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] bytes = new byte[8];
bos.write(bytes);
bos.writeTo(oos);

你可以创建一个ByteArrayOutputStream实例。然后需要将数据写入此ByteOutputStream实例并使用writeTo方法,该方法接受一个OutputStream,您可以使ByteArrayOutputStream能够将输出写入作为参数传递的OutputStream实例中。
希望这样可以解决问题!

我会尝试一下。 - Bill Smith
3
不,这将会向oos写入“nothing”(意味着bos为空)。 - eckes
我需要声明数组大小才能初始化吗?还是它会根据需要“增长”?我认为应该将其初始化为输出流的字节数。 - Bill Smith
你需要声明大小。数组不会动态增长。 - Rahul Bobhate
BAOS会自动调整支持数组的大小(如果需要,它会创建一个更大的数组并复制字节)。顺便说一句,它也可以管理数组列表,就像Apache的一些实现一样。 - eckes

-1

您可以在您的输出流上使用toByteArray函数。假设您有一个名为outputStream的缓冲区,那么您可以执行buffer.toByteArray操作。

如需了解更多信息,您可以查看Java中将输入流转换为字节数组的答案


OP想要从OutputStream创建一个ByteArrayOutputStream,而你正在使用InputStream! - Charlie
3
常规的输出流并不具备 tobytearray 方法。 - Bill Smith
我看了一下这个链接 https://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayOutputStream.html,其中展示了 toByteArray 方法。请仔细阅读一遍。 - cauchy
3
@cauchy 是的,java.io.ByteArrayOutputStream 有一个 toByteArray 方法,但是 java.io.OutputStream 没有。 - eckes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接