Apache Commons IO には便利なメソッドがあります IOUtils.toString()InputStream
を文字列に読み取ります。
私はApache Commonsから Guava :に移動しようとしているので、Guavaに同等のものはありますか? com.google.common.io
パッケージのすべてのクラスを調べましたが、これほど簡単なものは見つかりませんでした。
編集:文字セットの問題を理解し、感謝しています。すべてのソースがASCII(はい、ASCII、ANSIなどではありません)など)にあることを知っているので、この場合、エンコードは問題ではありません。
Calumの回答に対するコメントで、使用するつもりであると述べた
_CharStreams.toString(new InputStreamReader(supplier.get(), Charsets.UTF_8))
_
オーバーロードCharStreams.toString(Readable)
の状態は次のとおりです。
Readable
を閉じません。
これは、あなたのInputStreamReader
、および拡張によりsupplier.get()
によって返されるInputStream
は、このコードの完了後に閉じられないことを意味します。
一方、すでに_InputSupplier<InputStream>
_があり、オーバーロード_CharStreams.toString(InputSupplier<R extends Readable & Closeable>
_)を使用しているように見えるという事実を利用する場合、toString
メソッドは作成と終了の両方を処理しますあなたのためのReader
の。
これは、入力としてInputStream
を受け取る_CharStreams.newReaderSupplier
_のオーバーロードが実際にないことを除いて、Jon Skeetが提案したとおりです... 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
_ブロックを必要とする部分を処理できるようにして、リソースが適切に閉じられるようにすることで、生活を楽にすることです。
編集:個人的に、私は次のことを見つけました(実際にそれを書く方法は、上記のコードの手順を壊しただけです)
_String text = CharStreams.toString(
CharStreams.newReaderSupplier(supplier, Charsets.UTF_8));
_
farこれより冗長ではない:
_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月
InputSupplier
およびOutputSupplier
およびそれらを使用するメソッドは、Guava 16.0で非推奨になりました。それらの置換は、ByteSource
、CharSource
、ByteSink
、およびCharSink
です。 ByteSource
を指定すると、次のようにその内容をString
として取得できます。
_ByteSource source = ...
String text = source.asCharSource(Charsets.UTF_8).read();
_
Readable
がある場合は、CharStreams.toString(Readable)
を使用できます。したがって、おそらく次のことができます。
String string = CharStreams.toString( new InputStreamReader( inputStream, "UTF-8" ) );
文字セットを指定するように強制しますが、とにかく行うべきだと思います。
[〜#〜] update [〜#〜]:振り返ってみると、古いソリューションが気に入らない。それに加えて、それは現在2013年であり、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);
}
ほぼ。次のようなものを使用できます。
_InputSupplier<InputStreamReader> readerSupplier = CharStreams.newReaderSupplier
(streamSupplier, Charsets.UTF_8);
String text = CharStreams.toString(readerSupplier);
_
個人的に私はdo n'tはIOUtils.toString(InputStream)
が「いい」と思う-それは常にプラットフォームのデフォルトのエンコーディングを使用するからで、それはあなたが望むものとはほとんど決して違う。エンコーディングの名前を取得するオーバーロードがありますが、名前を使用することは素晴らしいアイデアではありません。だから_Charsets.*
_が好きです。
編集:上記がstreamSupplier
として_InputSupplier<InputStream>
_を必要とするわけではありません。既にストリームを取得している場合は、十分に簡単に実装できます。
_InputSupplier<InputStream> supplier = new InputSupplier<InputStream>() {
@Override public InputStream getInput() {
return stream;
}
};
_
別のオプションは、Streamからバイトを読み取り、それらから文字列を作成することです。
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);
}
}
入力ストリームがクラスパスリソースから来る場合、より短い自動クローズソリューションがあります。
URL resource = classLoader.getResource(path);
byte[] bytes = Resources.toByteArray(resource);
String text = Resources.toString(resource, StandardCharsets.UTF_8);
IOExplained に触発されたGuava Resources を使用します。
[〜#〜] edit [〜#〜](2015): Okio は、I/O私が知っているJava/Androidで。いつも使っています。
FWIWは私が使用するものです。
既に手元にストリームがある場合は、次のようにします。
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));
ストリームを作成している場合:
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;
}