相当于IOUtils.toString(InputStream)的番石榴

Sea*_*oyd 105 java io inputstream guava

Apache Commons IO有一个很好的方便方法IOUtils.toString()来读取InputStream一个String.

因为我试图从Apache Commons转移到Guava:在番石榴中是否有相同的东西?我查看了com.google.common.io包中的所有类,我找不到任何简单的东西.

编辑:我理解并欣赏charsets的问题.事实上,我知道所有的源都是ASCII(是的,ASCII,而不是ANSI等),所以在这种情况下,编码对我来说不是问题.

Col*_*inD 85

您在评论Calum的回答中说明了您将要使用的内容

CharStreams.toString(new InputStreamReader(supplier.get(), Charsets.UTF_8))
Run Code Online (Sandbox Code Playgroud)

此代码存在问题,因为过载CharStreams.toString(Readable)状态:

不关闭Readable.

这意味着在此代码完成后,您的InputStreamReader,以及InputStream返回的扩展supplier.get()名将不会被关闭.

另一方面,如果你利用了你似乎已经拥有InputSupplier<InputStream>并使用了重载的事实,那么CharStreams.toString(InputSupplier<R extends Readable & Closeable>toString方法将处理Reader你的创建和关闭.

这正是Jon Skeet建议的,除了实际上没有任何重载CharStreams.newReaderSupplier需要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);
Run Code Online (Sandbox Code Playgroud)

关键InputSupplier是通过允许Guava处理需要丑陋try-finally块的部件来确保资源正确关闭,从而使您的生活更轻松.

编辑:就个人而言,我发现以下(这是我实际编写它的方式,只是打破了上面代码中的步骤)

String text = CharStreams.toString(
    CharStreams.newReaderSupplier(supplier, Charsets.UTF_8));
Run Code Online (Sandbox Code Playgroud)

远远比这个更简洁:

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);
}
Run Code Online (Sandbox Code Playgroud)

这或多或少是你必须写的,以便自己妥善处理.


编辑:2014年2月

InputSupplier并且OutputSupplier在Guava 16.0中已经弃用了使用它们的方法.其接替者ByteSource,CharSource,ByteSinkCharSink.给定a ByteSource,您现在可以String像这样得到它的内容:

ByteSource source = ...
String text = source.asCharSource(Charsets.UTF_8).read();
Run Code Online (Sandbox Code Playgroud)

  • @TedM.Young:如果你只有一个`InputStream`,并且你想把它作为`String`,那么`CharStreams.toString(new InputStreamReader(inputStream,charset))`就是你的选择.`ByteSource`和`CharSource`专门用于你可以作为`InputStream`s或'reader`s的源的东西的情况. (4认同)

Cal*_*lum 56

如果你有一个Readable你可以使用CharStreams.toString(Readable).所以你可以做以下事情:

String string = CharStreams.toString( new InputStreamReader( inputStream, "UTF-8" ) );
Run Code Online (Sandbox Code Playgroud)

强制你指定一个字符集,我猜你应该这样做.

  • @SPFloyd:如果你有一个`InputSupplier <InputStream>`我强烈建议使用`CharStreams.newReaderSupplier(supplier,Charsets.UTF_8)`而不是`new InputStreamReader`.原因是当给出`InputStreamReader`时,`toString`将_not_关闭那个'Reader`(因而不是底层的流!).通过对`Reader`使用`InputSupplier`,`toString`方法将为您处理关闭`Reader`. (10认同)
  • 实际上,我将结合你和Jon Skeet的答案:`CharStreams.toString(new InputStreamReader(supplier.get(),Charsets.UTF_8)) (4认同)

hus*_*ayt 16

更新:回顾过去,我不喜欢我的旧解决方案.除了它现在是2013年,Java7现在有更好的替代品.所以我现在使用的是:

InputStream fis = ...;
String text;
try (  InputStreamReader reader = new InputStreamReader(fis, Charsets.UTF_8)){
        text = CharStreams.toString(reader);
}
Run Code Online (Sandbox Code Playgroud)

或者如果使用InputSupplier

InputSupplier<InputStreamReader> spl = ...
try (  InputStreamReader reader = spl.getInput()){
        text = CharStreams.toString(reader);
    }
Run Code Online (Sandbox Code Playgroud)


Jon*_*eet 15

几乎.你可以使用这样的东西:

InputSupplier<InputStreamReader> readerSupplier = CharStreams.newReaderSupplier
    (streamSupplier, Charsets.UTF_8);
String text = CharStreams.toString(readerSupplier);
Run Code Online (Sandbox Code Playgroud)

我个人认为这IOUtils.toString(InputStream)是"好" -因为它总是使用的平台,这是几乎从来没有你想要什么的默认编码.有一个重载,它采用编码的名称,但使用名称不是一个好主意IMO.这就是我喜欢的原因Charsets.*.

编辑:不是说上面需要的InputSupplier<InputStream>streamSupplier.如果你已经有了这个流,你可以很容易地实现它:

InputSupplier<InputStream> supplier = new InputSupplier<InputStream>() {
    @Override public InputStream getInput() {
        return stream;
    }
};
Run Code Online (Sandbox Code Playgroud)


pon*_*ndr 11

另一种选择是从Stream读取字节并从中创建一个String:

new String(ByteStreams.toByteArray(inputStream))
new String(ByteStreams.toByteArray(inputStream), Charsets.UTF_8)
Run Code Online (Sandbox Code Playgroud)

它不是'纯'番石榴,但它有点短.