问题
Apache Commons IO有一个很好的方便方法IOUtils.toString()读取anInputStream
到一个字符串。
因为我试图摆脱Apache Commons并转向Guava:Guava中有相同的东西吗?我查看了com.google.common.io
包中的所有类,我几乎找不到任何简单的东西。
**编辑:**我理解并欣赏charsets的问题。事实上,我知道我的所有源都是ASCII(是的,ASCII,而不是ANSI等),因此在这种情况下,编码对我来说不是问题。
#1 热门回答(80 赞)
你在评论Calum的回答中说明了你将要使用的内容
CharStreams.toString(new InputStreamReader(supplier.get(), Charsets.UTF_8))
这段代码有问题,因为overloadCharStreams.toString(Readable)
状态:
不关闭Readable。
这意味着在此代码完成后,你的InputStreamReader
以及经过扩展的InputStream
(由supplier.get()
返回)将不会被关闭。
另一方面,如果你利用了你似乎已经拥有InputSupplier<InputStream>
并使用了overloadCharStreams.toString(InputSupplier<R extends Readable & Closeable>
)的事实,那么53822242方法将为你处理Reader
的创建和关闭。
这正是Jon Skeet建议的,除了实际上没有任何超载4887402630需要输入InputStream
...你必须给它一个InputSupplier
:
InputSupplier<? extends InputStream> supplier = ...
InputSupplier<InputStreamReader> readerSupplier =
CharStreams.newReaderSupplier(supplier, Charsets.UTF_8);
// InputStream and Reader are both created and closed in this single call
String text = CharStreams.toString(readerSupplier);
通过允许Guava处理需要丑陋的try-finally
块的部件来确保资源正确关闭,这一点可以让你的生活更轻松。
**编辑:**另外,我发现以下内容(这就是我实际编写它的方式,只是打破了上面代码中的步骤)
String text = CharStreams.toString(
CharStreams.newReaderSupplier(supplier, Charsets.UTF_8));
比这更加冗长:
String text;
InputStreamReader reader = new InputStreamReader(supplier.get(),
Charsets.UTF_8);
boolean threw = true;
try {
text = CharStreams.toString(reader);
threw = false;
}
finally {
Closeables.close(reader, threw);
}
或多或少你要写的是为了自己处理这个问题。
编辑:2014年2月
475648935和OutputSupplier
以及使用它们的方法已在Guava 16.0中弃用。他们的替代品是ByteSource
,CharSource
,ByteSink
和CharSink
。鉴于aByteSource
,你现在可以将其内容设为aString
,如下所示:
ByteSource source = ...
String text = source.asCharSource(Charsets.UTF_8).read();
#2 热门回答(54 赞)
如果你有aReadable
你可以使用CharStreams.toString(Readable)
。所以你可以做以下事情:
String string = CharStreams.toString( new InputStreamReader( inputStream, "UTF-8" ) );
强制你指定一个字符集,我想你应该这样做。
#3 热门回答(15 赞)
几乎。你可以使用这样的东西:
InputSupplier<InputStreamReader> readerSupplier = CharStreams.newReaderSupplier
(streamSupplier, Charsets.UTF_8);
String text = CharStreams.toString(readerSupplier);
我个人认为IOUtils.toString(InputStream)
并不"很好" - 因为它总是使用平台的默认编码,这几乎不是你想要的。有一个重载,它采用编码的名称,但使用名称不是一个好主意IMO。这就是我喜欢Charsets.*
的原因。
编辑:不是以上需要anInputSupplier<InputStream>
asstreamSupplier
。如果你已经有了这个流,你可以很容易地实现它:
InputSupplier<InputStream> supplier = new InputSupplier<InputStream>() {
@Override public InputStream getInput() {
return stream;
}
};