ChatGPT解决这个技术问题 Extra ChatGPT

将 OutputStream 转换为字符串

将 java.io.OutputStream 的输出通过管道传输到 Java 中的 String 的最佳方法是什么?

说我有方法:

  writeToStream(Object o, OutputStream out)

它将某些数据从对象写入给定的流。但是,我想尽可能轻松地将此输出转换为字符串。

我正在考虑编写这样的课程(未经测试):

class StringOutputStream extends OutputStream {

  StringBuilder mBuf;

  public void write(int byte) throws IOException {
    mBuf.append((char) byte);
  }

  public String getString() {
    return mBuf.toString();
  }
}

但是有更好的方法吗?我只想做个测试!

你只有ASCII字节吗?你不需要代码页吗?
在这种情况下,是的。但是,好点 - 我没有考虑过。

0
0xCursor

我会使用 ByteArrayOutputStream。完成后,您可以致电:

new String( baos.toByteArray(), codepage );

或更好:

baos.toString( codepage );

对于 String 构造函数,codepage 可以是 Stringjava.nio.charset.Charset 的实例。可能的值为 java.nio.charset.StandardCharsets.UTF_8

方法 toString() 仅接受 String 作为 codepage 参数(支持 Java 8)。


ByteArrayOutputStream 没有 toArray() 方法;它确实有 toByteArray() 。你能修复答案吗?另外,为什么不使用 baos.toString(String charsetName) 会稍微简单一些。
字节数组只是二进制数据。由于(unicode)文本可以以多种不同的方式进行二进制编码,ByteArrayOutputStream 需要知道用于对字节进行编码的编码,因此它可以使用相同的编码再次将字节解码为字符串。简单地使用不带参数的 toString 是不明智的,因为您只是忽略了问题而不是解决它; Java 将使用可能正确的平台编码......或不正确。基本上是随机的。您需要找出用于将文本写入字节并将该编码传递给 toString 的编码。
只是对此处引用的代码页进行澄清:在 Java 中,您可以使用 Charset.defaultCharset() 或 Charset.forName("specific charset");对我有用的是: new String(baos.toByteArray(), Charset.defaultCharset());
@WallaceBrown 使用 defaultCharset 并不比完全忽略字符集好 - 您需要在使用 toString 之前找出它是什么
StandardCharsets.UTF_8Charset,而不是 String。此外,该参数称为 charsetName,而不是 codepage
M
Matthew

我喜欢 Apache Commons IO 库。查看它的 ByteArrayOutputStream 版本,它具有 toString(String enc) 方法和 toByteArray()。使用像 Commons 项目这样的现有和受信任的组件可以让你的代码更小,更容易扩展和重新利用。


为自己节省一年的生命,并通读所有常见的 API,这样当您遇到问题时,您可以推出经过全面测试且由社区拥有的解决方案。
嗯,我是一个狂热的 Apache Commons 用户,但在这种情况下,我不明白为什么应该使用 Commons IO 的 ByteArrayOutputStream 而不是 JDK 自己的 java.io.ByteArrayOutputStream。后者还提供 toString(String charsetName) 和 toByteArray() 方法。需要详细说明吗?
是的,由于原始上下文是流式传输和提取内容的更好方法,因此我包含了 Commons IO 示例,因为它包含用于填充 OutputStream 的当时未定义/有问题的机制的“write(InputStream)”方法。我也会选择 JDK。
M
Miss Chanandler Bong

这很好用

OutputStream output = new OutputStream() {
    private StringBuilder string = new StringBuilder();

    @Override
    public void write(int b) throws IOException {
        this.string.append((char) b );
    }

    //Netbeans IDE automatically overrides this toString()
    public String toString() {
        return this.string.toString();
    }
};

方法调用=>> marshaller.marshal( (Object) toWrite , (OutputStream) output);

然后打印字符串或获取它只是引用“输出”流本身作为示例,将字符串打印到控制台 =>> System.out.println(output);

仅供参考:我的方法调用 marshaller.marshal(Object,Outputstream) 用于处理 XML。与本主题无关。

这对于生产使用来说是非常浪费的,转换太多并且有点松散。这只是为了向您证明完全可以创建自定义 OuputStream 并输出字符串。但是只要走 Horcrux7 的方式,只需要两个方法调用就可以了。

世界生活在另一天......


仅将一个字节转换为 char 仅适用于 ascii。像 Horcrux7 一样使用 ByteArrayOutputStream
同意戴夫·雷。您不能假设您的字节是 ASCII 字符。您需要使用编码来解释字节。使用 byteArrayOutputStream.toString("UTF-8") 或 new String(byteArrayOutputStream.toByteArray(), "UTF-8")。
A
Adrian Mouat

这就是我最终做的事情:

Obj.writeToStream(toWrite, os);
try {
    String out = new String(os.toByteArray(), "UTF-8");
    assertTrue(out.contains("testString"));
} catch (UnsupportedEncondingException e) {
    fail("Caught exception: " + e.getMessage());
}

其中 os 是 ByteArrayOutputStream


@JavaJigs 我在将近 5 年前的回答底部澄清了这一点:)
考虑将 "UTF-8" 替换为 StandardCharsets.UTF_8
j
jschnasse
baos.toString(StandardCharsets.UTF_8);

通过使用命名字符集解码字节,将缓冲区的内容转换为字符串。

Java 17 - https://docs.oracle.com/