将OutputStream转换为字符串


580

将输出从java.io.OutputStream传递到Java中的String的最佳方法是什么?

说我有方法:

  writeToStream(Object o, OutputStream out)

它将某些数据从对象写入给定的流。但是,我希望将此输出尽可能容易地转换为String。

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

class StringOutputStream extends OutputStream {

  StringBuilder mBuf;

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

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

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


6
您只有ASCII字节吗?您不需要代码页吗?
Horcrux7

在这种情况下,可以。但是,好点-我没有考虑过。
阿德里安·穆阿特

Answers:


607

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

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

或更好:

baos.toString( codepage );

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

该方法toString()仅接受a String作为codepage参数(标准Java 8)。


8
ByteArrayOutputStream没有toArray()方法;它确实有toByteArray()。你能解决答案吗?另外,为什么不使用baos.toString(String charsetName)呢?
约尼克(Jonik)2009年

35
字节数组只是二进制数据。由于(unicode)文本可以通过许多不同的方式进行二进制编码,因此ByteArrayOutputStream需要知道使用哪种编码对字节进行编码,因此它可以使用相同的编码再次将字节解码为字符串。简单地使用不带参数的toString是不明智的,因为您只是忽略了问题而不是解决它。Java将使用可能正确或不正确的平台编码。基本上是随机的。您需要找出用于将文本写入字节的编码,然后将该编码传递给toString。
Stijn de Witt

10
只是澄清了此处引用的代码页:在Java中,您可以使用Charset.defaultCharset()或Charset.forName(“ specific charset”); 对我有用的是:new String(baos.toByteArray(),Charset.defaultCharset());
华莱士·布朗

7
@WallaceBrown使用defaultCharset并不比完全忽略的字符集-你需要找出什么是你使用之前toString
artbristol

4
StandardCharsets.UTF_8是一个Charset,而不是一个String。此外,该参数称为charsetName,而不是codepage
OrangeDog

46

我喜欢Apache Commons IO库。看看它的ByteArrayOutputStream版本,它具有和toString(String enc)方法toByteArray()。使用Commons项目之类的现有且受信任的组件,可使您的代码更小,更易于扩展和重新利用。


10
节省自己的生命,并通读所有通用的API,这样,当您遇到问题时,就可以释放出经过全面测试并由社区拥有的解决方案。
Bob Herrmann

15
嗯,我是一个狂热的Apache Commons用户,但是在这种情况下,我看不到为什么要使用Commons IO的ByteArrayOutputStream而不是JDK自己的java.io.ByteArrayOutputStream。后者还提供toString(String charsetName)和toByteArray()方法。关心详细吗?
约尼克(Jonik)2009年

1
是的,由于原始上下文是一种更好的流式传输和提取内容方式,因此,我包括了Commons IO示例,因为它包括了一种“ write(InputStream)”方法,用于填充输出流的当时未定义/可疑的机制。我也会选择JDK。
Joe Liversedge

23

这很好

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的方式,仅需两个方法调用就可以了。

世界生活在另一天。


9
仅将一个字节转换为char只能在ascii上工作。像Horcrux7一样使用ByteArrayOutputStream
Dave Ray

2
与Dave Ray达成协议。您不能假定您的字节是ASCII字符。您需要使用编码来解释字节。使用byteArrayOutputStream.toString(“ UTF-8”)或新的String(byteArrayOutputStream.toByteArray(),“ UTF-8”)。
马丁·陶

16

我最终要做的是:

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


2
@JavaJigs我在将近5年前的答案底部做了澄清:)
Adrian Mouat 2015年

19
考虑更换"UTF-8"StandardCharsets.UTF_8
james.garriss 2015年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.