IOUtils.toString(InputStream)相当于番石榴
Apache Commons IO有一个不错的方便方法IOUtils.toString()来读取一个InputStream
为一个String。
由于我正试图从Apache Commons转移到Guava :在Guava中是否有相当于? 我查看了com.google.common.io
包中的所有类,找不到任何简单的东西。
编辑:我理解和欣赏与charsets的问题。 只是碰巧我知道我所有的源都是ASCII(是的,ASCII,不是ANSI等),所以在这种情况下,编码对我来说不是问题。
你在你对Calum的回答的评论中表示你打算使用
CharStreams.toString(new InputStreamReader(supplier.get(), Charsets.UTF_8))
此代码是有问题的,因为重载CharStreams.toString(Readable)
指出:
不closures
Readable
。
这意味着你的InputStreamReader
和扩展名是由supplier.get()
返回的InputStream
,在这个代码完成后将不会被closures。
另一方面,如果您利用了您似乎已经拥有InputSupplier<InputStream>
并使用了重载CharStreams.toString(InputSupplier<R extends Readable & Closeable>
)的CharStreams.toString(InputSupplier<R extends Readable & Closeable>
, toString
方法将处理创build并为您closuresReader
。
这正是Jon Skeet所build议的,除了InputSupplier
实际上没有任何以InputStream
为input的重载之外,您必须给它一个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);
InputSupplier
在于通过允许Guava处理需要一个难看的try-finally
块的部分来确保资源正确closures,从而使您的生活更轻松。
编辑:个人而言,我发现以下(这是我如何写它,只是打破了上面的代码中的步骤)
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); }
这或多或less是你自己必须写的来处理这个问题。
编辑:2014年2月
InputSupplier
和OutputSupplier
以及使用它们的方法已经在Guava 16.0中被弃用了。 他们的替代品是ByteSource
, CharSource
, ByteSink
和CharSink
。 给定一个ByteSource
,你现在可以像下面这样获取它的内容:
ByteSource source = ... String text = source.asCharSource(Charsets.UTF_8).read();
如果你有一个Readable
你可以使用CharStreams.toString(Readable)
。 所以你可以做下面的事情:
String string = CharStreams.toString( new InputStreamReader( inputStream, "UTF-8" ) );
强制你指定一个字符集,我想你应该做的无论如何。
几乎。 你可以使用这样的东西:
InputSupplier<InputStreamReader> readerSupplier = CharStreams.newReaderSupplier (streamSupplier, Charsets.UTF_8); String text = CharStreams.toString(readerSupplier);
就我个人而言,我不认为IOUtils.toString(InputStream)
是“很好” – 因为它总是使用平台的默认编码,这几乎从来没有你想要的。 有一个重载,它采用编码的名称,但使用名称是不是一个好主意IMO。 这就是为什么我喜欢Charsets.*
。
编辑:不是说上面需要一个InputSupplier<InputStream>
作为streamSupplier
。 如果你已经有了这个stream,你可以很容易地实现:
InputSupplier<InputStream> supplier = new InputSupplier<InputStream>() { @Override public InputStream getInput() { return stream; } };
更新 :回顾一下,我不喜欢我的旧解决scheme。 除了现在是2013年,现在有更好的select可用于Java7。 所以这里是我现在使用的:
InputStream fis = ...; String text; try ( InputStreamReader reader = new InputStreamReader(fis, Charsets.UTF_8)){ text = CharStreams.toString(reader); }
或者如果使用InputSupplier
InputSupplier<InputStreamReader> spl = ... try ( InputStreamReader reader = spl.getInput()){ text = CharStreams.toString(reader); }
另一种select是从Stream中读取字节并从中创build一个string:
new String(ByteStreams.toByteArray(inputStream)) new String(ByteStreams.toByteArray(inputStream), Charsets.UTF_8)
这不是“纯”的番石榴,但是稍微短一些。
基于接受的答案,这里是一个实用的方法,嘲笑IOUtils.toString()
的行为(以及一个带有字符集的重载版本)。 这个版本应该是安全的,对吧?
public static String toString(final InputStream is) throws IOException{ return toString(is, Charsets.UTF_8); } public static String toString(final InputStream is, final Charset cs) throws IOException{ Closeable closeMe = is; try{ final InputStreamReader isr = new InputStreamReader(is, cs); closeMe = isr; return CharStreams.toString(isr); } finally{ Closeables.closeQuietly(closeMe); } }
在inputstream来自classpath资源的情况下,自动closures解决scheme的时间要短得多:
URL resource = classLoader.getResource(path); byte[] bytes = Resources.toByteArray(resource); String text = Resources.toString(resource, StandardCharsets.UTF_8);
受IOExplained启发,使用番石榴资源 。
编辑 (2015): Okio是我知道的Java / Android中I / O的最佳抽象和工具。 我用它所有的时间。
FWIW这是我使用的。
如果我已经有一个stream,那么:
final InputStream stream; // this is received from somewhere String s = CharStreams.toString(CharStreams.newReaderSupplier(new InputSupplier<InputStream>() { public InputStream getInput() throws IOException { return stream; } }, Charsets.UTF_8));
如果我正在创build一个stream:
String s = CharStreams.toString(CharStreams.newReaderSupplier(new InputSupplier<InputStream>() { public InputStream getInput() throws IOException { return <expression creating the stream>; } }, Charsets.UTF_8));
作为一个具体的例子,我可以像这样读取Android文本文件资源:
final Context context = ...; String s = CharStreams.toString(CharStreams.newReaderSupplier(new InputSupplier<InputStream>() { public InputStream getInput() throws IOException { return context.getAssets().open("my_asset.txt"); } }, Charsets.UTF_8));
举一个具体的例子,我可以读取一个Android文本文件资源:
public static String getAssetContent(Context context, String file) { InputStreamReader reader = null; InputStream stream = null; String output = ""; try { stream = context.getAssets().open(file); reader = new InputStreamReader(stream, Charsets.UTF_8); output = CharStreams.toString(reader); } catch (IOException e) { e.printStackTrace(); } finally { if (stream != null) { try { stream.close(); } catch (IOException e) { e.printStackTrace(); } } if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return output; }
- 对于每个可能返回null的方法,我应该使用Java8 / Guava Optional吗?
- HashMap的build设者
- 番石榴:为什么没有Lists.filter()函数?
- 使用Google Guava的Objects.ToStringHelper
- 如何使用Google集合将List <String>转换为Map <String,String>?
- Google-guava checkNotNull和IntelliJ IDEA的“可能会产生java.lang.NullPointerException”
- 番石榴和Apache等效库有什么大的改进?
- 如何从Guava的List中获取max()元素
- Java的番石榴图书馆; 它最有用和/或隐藏的特性是什么?