Get an OutputStream into a String
将Java.Io.OuttoString的输出管到Java中的字符串的最佳方法是什么?
假设我有方法:
它将对象中的某些数据写入给定的流。但是,我希望尽可能容易地将这个输出转换成一个字符串。
我正在考虑写这样一个类(未经测试):
1 2 3 4 5 6 7 8 9 10 11 12
| class StringOutputStream extends OutputStream {
StringBuilder mBuf ;
public void write (int byte) throws IOException {
mBuf. append((char) byte);
}
public String getString () {
return mBuf. toString();
}
} |
但是有更好的方法吗?我只想做个测试!
- 你只有ASCII字节吗?你不需要代码页吗?
- 在这种情况下,是的。不过,说得对-我没想过。
我会用一个ByteArrayOutputStream。完成后,你可以打电话:
1
| new String( baos. toByteArray(), codepage ); |
或更好
1
| baos.toString( codepage ); |
对于字符串构造函数,codepage可以是字符串或java.nio.charset.charset的实例。可能的值是java.nio.charset.standardcharset.utf_8。
ToString方法只接受一个字符串作为EDCOX1×1参数(Read Java 8)。
- BytearrayOutputStream没有toArray()方法;但它确实有toBytearray()。你能解决这个问题吗?另外,为什么不使用bao.toString(string charsetname),这会稍微简单一些。
- 感谢您提供ToString(Charset)的提示。我从来没有看过toString,因为我期待一个bytearrayOutputstream@123456。我还纠正了tobytearray()的错误。
- 另外请注意,除非您通过自定义安装明确要求某些代码页,否则不会安装它们。
- 可以简单返回bao.toString(),coepage的作用是什么?
- 字节数组只是二进制数据。由于(unicode)文本可以以多种不同的方式进行二进制编码,bytearrayOutputstream需要知道使用什么编码来编码字节,因此它可以使用相同的编码再次将字节解码为字符串。简单地使用ToStand不带参数是不明智的,因为你只是忽略了问题而不是解决它;Java将使用平台编码,这可能是正确的或不正确的。基本上是随机的。您需要找出用于将文本写入字节并将该编码传递给ToString的编码方式。
- 你能在答案中提供一个代码示例吗?
- 对这里引用的代码页进行了澄清:在Java中,您可以使用字符集.DaultCARSSET()或字符集(FordNeal.FordNead);对我来说工作的是:新字符串(Boo.ToBytErayRaye),字符集.Debug THARSETSER();
- @使用defaultCharset的wallaceborn并不比完全忽略字符集好——在使用toString之前,您需要了解它是什么。
- @Artbristol:虽然你关于defaultCharset的警告在技术上是正确的,但对于这个例子(一个单元测试),它似乎无关紧要——字符串将在同一台机器上,在同一个程序执行期间进行编码和解码。使用不同的代码页确实没有风险。
- @是的,你是对的,如果它在同一台机器上编码和解码,那就好了。不过,如果单元测试将结果与某个固定字符串进行比较呢?
- @只有当作者也使用defaultCharset时,才会自动切换。
- StandardCharsets.UTF_8是Charset,不是String。此外,该参数称为charsetName,而不是codepage。
我喜欢Apache Commons IO库。看看它的bytearrayOutputstream版本,它有一个toString(String enc)方法和toByteArray()方法。使用现有的和可信的组件(如Commons项目)可以使代码更小、更容易扩展和重新调整用途。祝你好运。
- 为你自己节省一年的时间,阅读所有公共的API,这样当你遇到问题时,你就可以发布一个完全测试过的社区拥有的解决方案。
- 嗯,我是一个狂热的ApacheCommons用户,但在这种情况下,我不明白为什么你应该使用Commons IO的BytearrayOutputstream而不是JDK自己的java.io.BytearrayOutputstream。后者还提供toString(string charsetname)和tobytearray()方法。想详细说明吗?
- 是的,因为原始上下文是一种更好的流式和提取内容的方法,所以我包括了commons IO示例,因为它包含了一个"write(inputstream)"方法,用于填充输出流的当时未定义/可疑的机制。我也会和JDK一起去。
这很管用
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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);。
然后打印或获取字符串,只需引用"输出"流本身例如,将字符串输出到console=>>System.out.println(output);。
仅供参考:我的方法调用marshaller.marshal(Object,Outputstream)用于处理XML。这与这个话题无关。
这对于生产性使用是非常浪费的,有一个方法转换太多,而且有点松散。这只是为了向您证明完全可以创建自定义的ouputstream并输出字符串。但只要按Horcrux7的方式进行,只需两个方法调用就可以了。
世界就在另一天…
- 只需将一个字节转换为字符,就只能在ASCII上工作。像Horcrux7一样使用BytearrayOutputstream
- 同意戴夫·雷。您不能假定您的字节是一个ASCII字符。您需要使用编码来解释字节。使用bytearrayOutputstream.toString("utf-8")或新字符串(bytearrayOutputstream.tobytearray(),"utf-8")。
我最后做的是:
1 2 3 4 5 6 7
| 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。
- 您的代码中的"OS"是什么?
- @Javajigs我在5年前的答案底部澄清了这一点。)
- 考虑用StandardCharsets.UTF_8替换"UTF-8"。