将 ByteArrayInputStream 的内容转换为字符串

Posted

技术标签:

【中文标题】将 ByteArrayInputStream 的内容转换为字符串【英文标题】:Convert Contents Of A ByteArrayInputStream To String 【发布时间】:2014-07-26 09:24:24 【问题描述】:

我读了this post,但我没有关注。我见过this,但还没有看到使用ByteArrayOutputStreamByteArrayInputStream 转换为String 的正确示例。

要将ByteArrayInputStream 的内容作为String 检索,是推荐使用ByteArrayOutputstream 还是有更好的方法?

我正在考虑使用this example 并扩展ByteArrayInputStream 并利用Decorator 来增加运行时的功能。有兴趣将其作为使用ByteArrayOutputStream 的更好解决方案吗?

【问题讨论】:

您可能需要InputStreamReader,如您提供的第二个链接中所述。 ByteArrayOutputStream 不会将字节转换为字符。 你真的有一个 ByteArrayInputStream(这意味着你有一个 byte[])还是你只有一个 InputStream? @BrettOkken 我真的有一个 ByteArrayInputStream,它的构造函数被传递了一个字节数组(不同大小) @DavidWallace 在第二个链接中使用 InputstreamReader 回复了帖子:The problem with this is that it reads only up to and including the first line separator. It assumes that the string you're looking for does not contain any line separators. Often that's true, but if not, this won't really work. 为什么我不继续那个例子。 但是你可以一直读到它为空。 【参考方案1】:

使用 Scanner 并将 ByteArrayInputStream 传递给它的构造函数,然后从您的 Scanner 读取数据,检查此示例:

ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(new byte[]  65, 80 );
Scanner scanner = new Scanner(arrayInputStream);
scanner.useDelimiter("\\Z");//To read all scanner content in one String
String data = "";
if (scanner.hasNext())
    data = scanner.next();
System.out.println(data);

【讨论】:

如果我有XMLhtml 文档,我可以不受限制地阅读吗? 是的,没有限制。【参考方案2】:

ByteArrayOutputStream 可以从任何InputStream 中读取,最后产生byte[]

不过使用ByteArrayInputStream 会更简单:

int n = in.available();
byte[] bytes = new byte[n];
in.read(bytes, 0, n);
String s = new String(bytes, StandardCharsets.UTF_8); // Or any encoding.

对于ByteArrayInputStream available() 产生总字节数。


附录 2021-11-16

从 java 9 开始,您可以使用较短的 readAllBytes。

byte[] bytes = in.readAllBytes();

回复评论:使用 ByteArrayOutputStream

ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[8192];
for (;;) 
    int nread = in.read(buf, 0, buf.length);
    if (nread <= 0) 
        break;
    
    baos.write(buf, 0, nread);

in.close();
baos.close();
byte[] bytes = baos.toByteArray();

这里可能是任何 InputStream。


从 java 10 开始还有一个ByteArrayOutputStream#toString(Charset)

String s = baos.toString(StandardCharsets.UTF_8);

【讨论】:

如何从 ByteArrayInputStream 读取 ByteArrayOutputStream? 我已经扩展了答案。原则上,一个循环从InputStream 读取并写入ByteArrayOutputStream。与传统不同的是,I/O 缓冲区的大小是 2 的幂。 同意2大小的幂;我喜欢,谢谢。 来自InputStream.available()函数的javadoc:使用这个方法的返回值来分配一个缓冲区来保存这个流中的所有数据是不正确的。 @nucatus 是的,我没有说in 就是ByteArrayInputStream。对于ByteArrayInputStream#available() 一个可能。【参考方案3】:

使用 Base64 编码

假设你有你的 ByteArrayOutputStream :

ByteArrayOutputStream baos =...
String s = new String(Base64.Encoder.encode(baos.toByteArray()));

见http://docs.oracle.com/javase/8/docs/api/java/util/Base64.Encoder.html

【讨论】:

不错的解决方案。但是,我需要先将我的 ByteArrayInputStream 连接到我的 ByteArrayOutputStream。这是如何实现的? 重要的是要说 Base64.Encoder 是在 Java 8 中发布的。:) 应该是 String s = new String(Base64.getEncoder().encode(baos.toByteArray()));不过谢谢。 正如@SiddharthGharge 所说,编码器创建错误。还有一个问题是关于 InputStream,而不是 OutputStream。【参考方案4】:

为什么没有人提到org.apache.commons.io.IOUtils

import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;

String result = IOUtils.toString(in, StandardCharsets.UTF_8);

只有一行代码。

【讨论】:

我添加了两个必需的import 语句,因此不是每个人都必须搜索它们。抱歉……它不再只是一行代码了;) 对不起,我认为这个答案不正确。因为如果你的输入是 ByteArrayInputStream 你会得到编译错误。这个函数的正确输入是 InputStream【参考方案5】:

Java 9+ 解决方案:

new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);

【讨论】:

以上是关于将 ByteArrayInputStream 的内容转换为字符串的主要内容,如果未能解决你的问题,请参考以下文章

使用 java.io 寻找 ByteArrayInputStream

如何正确地将 Blob 对象转换为 ByteArrayInputStream 对象? [复制]

java:内存处理ByteArrayOutputStream,ByteArrayInputStream

内存操作流

字节输入流----ByteArrayInputStream

JDK源码:ByteArrayInputStream