JavaでInputStreamをどのように読み取り/変換しますか?


4063

java.io.InputStreamオブジェクトがある場合、そのオブジェクトをどのように処理して、String


InputStreamテキストデータを含むがあり、それをに変換したいとしStringます。たとえば、それをログファイルに書き込むことができます。

を取得してInputStreamに変換する最も簡単な方法は何Stringですか?

public String convertStreamToString(InputStream is) {
    // ???
}

36
この質問に対する答えは、ストリームのコンテンツを完全に(閉じられるまで)読みたい場合にのみ機能します。これは常に意図されているわけではないため(キープアライブ接続のあるHTTPリクエストは閉じられません)、これらのメソッド呼び出しはブロックします(コンテンツを提供しません)。
f1sh

21
コードが実行されるマシン/オペレーティングシステム/プラットフォームまたはそのバージョンに応じてランダムに選択されたエンコーディングを使用するため、ストリームの文字エンコーディングを知って指定する必要があります。そうしない、文字エンコーディングのバグが発生します。つまり、プラットフォームのデフォルトのエンコーディングに依存するメソッドを使用しないでください。
ChristofferHammarström2010

11
9年前の自分のコメントを楽しむために、最近、Groovyの「String s = new File( "SomeFile.txt")。text」を使用してファイル全体を一度に読み取ると、うまく機能します。私は非プロダクション(スクリプト)コードにgroovyを使用することに満足しています-正直に言うと、Javaが行うようにエンコーディングと非常に長いファイルに対処することを強制することは、とにかくプロダクションコードにとって本当に良いアイデアなので、それはその目的のために機能します、 Groovyは、Javaが得意ではないクイックスクリプトで動作します。ジョブに適したツールを使用するだけで、問題は解決します。
Bill K

単純化するだけ: ByteArrayOutputStream outputBytes = new ByteArrayOutputStream(); for(byte[] b = new byte[512]; 0 < inputStream.read(b); outputBytes.write(b)); return new String(outputBytes.toByteArray(), StandardCharsets.UTF_8);
Felypp Oliveira 2017

@BillKをJava 11で使用するString s = Files.readString​(Path.of("SomeFile.txt"));と、言語で可能な限り優れた機能を使用できます。これにより、説明したような魔法の型変換はサポートされません。
ホルガー

回答:


2530

これを行う良い方法は、Apache commons IOUtilsを使用InputStreamしてStringWriter... にコピーすることです

StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, encoding);
String theString = writer.toString();

あるいは

// NB: does not close inputStream, you'll have to use try-with-resources for that
String theString = IOUtils.toString(inputStream, encoding); 

または、ByteArrayOutputStreamストリームとライターを混在させたくない場合に使用できます。


75
Android開発者にとって、AndroidにはApacheのIOUtilsが付属していないようです。したがって、他の回答を参照することを検討してください。
Chris.Zou 2014

47
これは現時点で信じられないほど古い質問です(2008年に尋ねられました)。より現代的な答えを読むことは、あなたの時間の価値があります。Java 8ライブラリからのネイティブ呼び出しを使用するものもあります。
Shadoninja 2016年

36
この回答は非常に古く、それをそのようにマークできるはずです(残念ながら、これは不可能です)。
codepleb

7
IOUtils.toString()は長い間推奨されていません。この答えは間違いなくもう推奨される方法ではありません。
Roshan

7
次に、それを編集して、将来の読者を支援するために非推奨になっている理由を説明します。
ジャン=フランソワ・ファーブル

2487

他の回答を要約します。これを行うための11の主な方法を見つけました(以下を参照)。そして、私はいくつかのパフォーマンステストを書きました(以下の結果を参照してください):

InputStreamを文字列に変換する方法:

  1. IOUtils.toString(Apache Utils)の使用

    String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
  2. CharStreams(Guava)の使用

    String result = CharStreams.toString(new InputStreamReader(
          inputStream, Charsets.UTF_8));
  3. Scanner(JDK)の使用

    Scanner s = new Scanner(inputStream).useDelimiter("\\A");
    String result = s.hasNext() ? s.next() : "";
  4. 使用するストリームAPI(Javaの8)。警告:このソリューションは、異なる改行(など\r\n)をに変換し\nます。

    String result = new BufferedReader(new InputStreamReader(inputStream))
      .lines().collect(Collectors.joining("\n"));
  5. 使用する並列ストリームAPI(Javaの8)。警告:このソリューションは、異なる改行(など\r\n)をに変換し\nます。

    String result = new BufferedReader(new InputStreamReader(inputStream)).lines()
       .parallel().collect(Collectors.joining("\n"));
  6. InputStreamReaderおよびStringBuilder(JDK)の使用

    final int bufferSize = 1024;
    final char[] buffer = new char[bufferSize];
    final StringBuilder out = new StringBuilder();
    Reader in = new InputStreamReader(stream, StandardCharsets.UTF_8);
    int charsRead;
    while((charsRead = in.read(buffer, 0, buffer.length)) > 0) {
        out.append(buffer, 0, charsRead);
    }
    return out.toString();
  7. 使用するStringWriterと、IOUtils.copy(Apacheのコモンズ)

    StringWriter writer = new StringWriter();
    IOUtils.copy(inputStream, writer, "UTF-8");
    return writer.toString();
  8. ByteArrayOutputStreamおよびinputStream.read(JDK)の 使用

    ByteArrayOutputStream result = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int length;
    while ((length = inputStream.read(buffer)) != -1) {
        result.write(buffer, 0, length);
    }
    // StandardCharsets.UTF_8.name() > JDK 7
    return result.toString("UTF-8");
  9. BufferedReader(JDK)を使用します。警告:このソリューションは、異なる改行(など\n\r)をline.separatorシステムプロパティに変換します(たとえば、Windowsでは "\ r \ n")。

    String newLine = System.getProperty("line.separator");
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    StringBuilder result = new StringBuilder();
    boolean flag = false;
    for (String line; (line = reader.readLine()) != null; ) {
        result.append(flag? newLine: "").append(line);
        flag = true;
    }
    return result.toString();
  10. BufferedInputStreamおよびByteArrayOutputStream(JDK)の使用

    BufferedInputStream bis = new BufferedInputStream(inputStream);
    ByteArrayOutputStream buf = new ByteArrayOutputStream();
    int result = bis.read();
    while(result != -1) {
        buf.write((byte) result);
        result = bis.read();
    }
    // StandardCharsets.UTF_8.name() > JDK 7
    return buf.toString("UTF-8");
  11. inputStream.read()およびStringBuilder(JDK)を使用します。警告:このソリューションには、ロシア語のテキストなどのUnicodeに関する問題があります(非Unicodeテキストでのみ正しく機能します)

    int ch;
    StringBuilder sb = new StringBuilder();
    while((ch = inputStream.read()) != -1)
        sb.append((char)ch);
    reset();
    return sb.toString();

警告

  1. ソリューション4、5、および9は、異なる改行を1つに変換します。

  2. ソリューション11はUnicodeテキストを正しく処理できません

性能試験

小さなString(長さ= 175)、githubの URLのパフォーマンステスト(モード=平均時間、システム= Linux、スコア1,343が最高):

              Benchmark                         Mode  Cnt   Score   Error  Units
 8. ByteArrayOutputStream and read (JDK)        avgt   10   1,343 ± 0,028  us/op
 6. InputStreamReader and StringBuilder (JDK)   avgt   10   6,980 ± 0,404  us/op
10. BufferedInputStream, ByteArrayOutputStream  avgt   10   7,437 ± 0,735  us/op
11. InputStream.read() and StringBuilder (JDK)  avgt   10   8,977 ± 0,328  us/op
 7. StringWriter and IOUtils.copy (Apache)      avgt   10  10,613 ± 0,599  us/op
 1. IOUtils.toString (Apache Utils)             avgt   10  10,605 ± 0,527  us/op
 3. Scanner (JDK)                               avgt   10  12,083 ± 0,293  us/op
 2. CharStreams (guava)                         avgt   10  12,999 ± 0,514  us/op
 4. Stream Api (Java 8)                         avgt   10  15,811 ± 0,605  us/op
 9. BufferedReader (JDK)                        avgt   10  16,038 ± 0,711  us/op
 5. parallel Stream Api (Java 8)                avgt   10  21,544 ± 0,583  us/op

githubString内の大きな(長さ= 50100)、URLのパフォーマンステスト(モード=平均時間、システム= Linux、スコア200,715が最高):

               Benchmark                        Mode  Cnt   Score        Error  Units
 8. ByteArrayOutputStream and read (JDK)        avgt   10   200,715 ±   18,103  us/op
 1. IOUtils.toString (Apache Utils)             avgt   10   300,019 ±    8,751  us/op
 6. InputStreamReader and StringBuilder (JDK)   avgt   10   347,616 ±  130,348  us/op
 7. StringWriter and IOUtils.copy (Apache)      avgt   10   352,791 ±  105,337  us/op
 2. CharStreams (guava)                         avgt   10   420,137 ±   59,877  us/op
 9. BufferedReader (JDK)                        avgt   10   632,028 ±   17,002  us/op
 5. parallel Stream Api (Java 8)                avgt   10   662,999 ±   46,199  us/op
 4. Stream Api (Java 8)                         avgt   10   701,269 ±   82,296  us/op
10. BufferedInputStream, ByteArrayOutputStream  avgt   10   740,837 ±    5,613  us/op
 3. Scanner (JDK)                               avgt   10   751,417 ±   62,026  us/op
11. InputStream.read() and StringBuilder (JDK)  avgt   10  2919,350 ± 1101,942  us/op

グラフ(Windows 7システムの入力ストリームの長さに応じたパフォーマンステスト)
ここに画像の説明を入力してください

Windows 7システムでの入力ストリームの長さに応じたパフォーマンステスト(平均時間):

 length  182    546     1092    3276    9828    29484   58968

 test8  0.38    0.938   1.868   4.448   13.412  36.459  72.708
 test4  2.362   3.609   5.573   12.769  40.74   81.415  159.864
 test5  3.881   5.075   6.904   14.123  50.258  129.937 166.162
 test9  2.237   3.493   5.422   11.977  45.98   89.336  177.39
 test6  1.261   2.12    4.38    10.698  31.821  86.106  186.636
 test7  1.601   2.391   3.646   8.367   38.196  110.221 211.016
 test1  1.529   2.381   3.527   8.411   40.551  105.16  212.573
 test3  3.035   3.934   8.606   20.858  61.571  118.744 235.428
 test2  3.136   6.238   10.508  33.48   43.532  118.044 239.481
 test10 1.593   4.736   7.527   20.557  59.856  162.907 323.147
 test11 3.913   11.506  23.26   68.644  207.591 600.444 1211.545

17
「要約回答」を書いているとき、いくつかの解決策は、場合によっては望ましくない可能性があるさまざまな改行(など\r\n)を自動的に変換することに注意してください\n。また、必要な追加のメモリ、または少なくとも割り当てのプレッシャーを確認できると便利です(少なくとも、JMHをで実行できます-prof gc)。本当にクールな投稿の場合は、グラフを表示すると便利です(同じ入力サイズ内の文字列の長さと、同じ文字列長内の入力サイズによって異なります)。
Tagir Valeev、2016

16
賛成。最もおかしなことは、結果が予想以上であることです。標準のJDKまたはApache Commons、あるいはその両方を使用する必要があります。
Aleksei Matiushkin 16

25
素晴らしいポスト。たった一つ。Java 8は、ロックと待機を強制するリソース(この入力ストリームなど)で並列ストリームを使用しないよう警告しているため、並列ストリームオプションは扱いにくく、価値がありませんか?
マングスブラザー2016年

10
並列ストリームは実際に行の順序を維持していますか?
Natix 2016

6
reset()例11の目的は何ですか?
Rob Stewart

2307

標準のJavaライブラリのみを使用する方法は次のとおりです(ストリームが閉じられていないことに注意してください。距離は異なる場合があります)。

static String convertStreamToString(java.io.InputStream is) {
    java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
}

私は「愚かなスキャナーのトリック」の記事からこのトリックを学びました。これが機能する理由は、スキャナーがストリーム内のトークンを反復処理するためです。この場合、「入力境界の先頭」(\ A)を使用してトークンを分離し、ストリームのコンテンツ全体に対して1つのトークンのみを提供します。

入力ストリームのエンコーディングについて特定する必要がある場合は、Scanner使用する文字セットを示すコンストラクタに2番目の引数を指定できます(例: "UTF-8")。

帽子のヒントはジェイコブにも行きます。


8
おかげで、このバージョンでは、入力ストリームを閉じるfinallyブロックを追加したので、入力の読み取りが終わったので、ユーザーが操作する必要はありません。呼び出し元のコードを大幅に簡略化します。

4
@PavelRepin @Patrick私の場合、空のinputStreamが原因でScannerの構築中にNPEが発生しました。if (is == null) return "";メソッドの最初に追加する必要がありました。nullのinputStreamsをより適切に処理するには、この回答を更新する必要があると思います。
CFL_Jeff 2012

115
:Javaの7のために、あなたは、try-として閉じることができます try(java.util.Scanner s = new java.util.Scanner(is)) { return s.useDelimiter("\\A").hasNext() ? s.next() : ""; }
earcam

5
残念ながら、この解決策は私の基になるストリーム実装でスローされた例外を実行して失うようです。
Taig 2013

11
FYI、hasNextメソッドは、コンソール入力ストリーム上のブロック(参照ここ)。(今、この問題に遭遇しただけです。)このソリューションはそれ以外の場合は正常に機能します...
ライアン14

848

Apache Commonsでは次のことが可能です。

String myString = IOUtils.toString(myInputStream, "UTF-8");

もちろん、UTF-8以外の文字エンコーディングを選択することもできます。

また見なさい:(ドキュメンテーション


1
また、デフォルトのエンコーディングで見つかった場合にのみ、inputStream引数を取るメソッドがあります。
ギヨームコテ

13
@GuillaumeCotéここでのメッセージは、Javaコードが実行されているプラ​​ットフォームによっては、何であるかわからないため、「デフォルトのエンコーディングで細かくする」ことは決してできないということだと思います。
Wiklanderによる2011

7
@Per Wiklander私はあなたに同意しません。シングルで動作するコードは、デフォルトのエンコーディングで問題ないことを確信できます。ローカルファイルのみを開くコードの場合、プラットフォームのデフォルトのエンコードでエンコードするように依頼するのが妥当なオプションです。
ギヨームコテ

39
グーグルの手間を省くために-<dependency> <groupId> org.apache.commons </ groupId> <artifactId> commons-io </ artifactId> <version> 1.3.2 </ version> </ dependency>
Chris

7
また、プレーンストリングリテラルを使用する代わりに、文字エンコーディングにapache io(またはその他の)定数を使用することもほとんど改善されません。例:IOUtils.toString(myInputStream、Charsets.UTF_8);

300

ファイルを考慮すると、最初にjava.io.Readerインスタンスを取得する必要があります。次に、これを読み取ってaに追加できますStringBuilderStringBuffer複数のスレッドでアクセスしていない場合は必要なく、StringBuilder高速です)。ここでの秘訣は、ブロックで作業するため、他のバッファリングストリームを必要としないことです。ブロックサイズは、実行時のパフォーマンス最適化のためにパラメーター化されています。

public static String slurp(final InputStream is, final int bufferSize) {
    final char[] buffer = new char[bufferSize];
    final StringBuilder out = new StringBuilder();
    try (Reader in = new InputStreamReader(is, "UTF-8")) {
        for (;;) {
            int rsz = in.read(buffer, 0, buffer.length);
            if (rsz < 0)
                break;
            out.append(buffer, 0, rsz);
        }
    }
    catch (UnsupportedEncodingException ex) {
        /* ... */
    }
    catch (IOException ex) {
        /* ... */
    }
    return out.toString();
}

8
このソリューションはマルチバイト文字を使用します。この例では、Unicodeの全範囲(中国語を含む)を表現できるUTF-8エンコードを使用しています。「UTF-8」を別のエンコーディングに置き換えると、そのエンコーディングを使用できるようになります。
Paul de Vrieze、

27
@ User1-コードでライブラリを使用するのが好きなので、仕事を早く終わらせることができます。マネージャーが「ワォジェームス!どうやってそんなに早くやったの?!」と言ったのは素晴らしいことです。しかし、一般的で再利用可能な、テスト済みのユーティリティを含めることについての考えを誤ったために、車輪の再発明に時間を費やす必要がある場合、プロジェクトの目標を進めるために費やすことができる時間をあきらめています。ホイールを再発明するとき、私たちは2倍の努力をしますが、ずっと後にゴールに到達します。フィニッシュラインになったら、祝う人はいません。家を建てるときは、あまりにもハンマーを構築していない
jmort253

10
申し訳ありませんが、私のコメントをもう一度読んだ後、それは少し傲慢になります。私はちょうど:)可能性があった非常によく、その理由が正当なものであると、回避ライブラリへの十分な理由を持っていることが重要だと思うと
jmort253

4
@ jmort253製品のライブラリを数回更新した後、パフォーマンスの低下に気づきました。幸い、私たちは独自の製品を構築して販売しているため、いわゆる期限はありません。残念ながら、多くのJVM、データベース、アプリケーションサーバーで利用できる製品を多くのオペレーティングシステムで構築しているため、貧弱なマシンを使用しているユーザーを考慮しなければなりません...そして、文字列操作を最適化すると、パフォーマンスが30〜40%向上します。そして修正:In our product, I even replaced「置き換えさえ」すべきです。
coolcfan

10
@ jmort253すでにApache Commonsを使用しているのであれば、私はそう思います。同時に、ライブラリの使用には実際のコストがかかります(多くのapache Javaライブラリでの依存関係の急増が示すように)。これがライブラリの唯一の使用である場合、ライブラリを使用するのはやりすぎです。一方、独自のバッファサイズを決定すると、メモリ/プロセッサの使用バランスを調整できます。
Paul de Vrieze、2012年

248

使用する:

InputStream in = /* Your InputStream */;
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String read;

while ((read=br.readLine()) != null) {
    //System.out.println(read);
    sb.append(read);
}

br.close();
return sb.toString();

11
重要なのは、最初に行に分割し、それを元に戻すことです。任意のバッファを読み取るだけの方が簡単で高速です。
ポールドブリーズ

20
また、readLineは\ nと\ rを区別しないため、正確なストリームを再度再生することはできません。
マリアアリアスデレイナドミンゲス2012

2
readLineEOLを探すために文字ごとに読み取るため、非常に非効率的です。また、ストリームに改行がない場合、これは実際には意味がありません。
njzk2 14

3
@Gops AB:これを試してみて、サンプルに改行が含まれている場合、このループがreadline()とStringBuilder.append()を使用して構築されている方法では、実際には改行が保持されないことがわかります。
Russ Bateman

4
厳密にバイトインバイトアウトではないため、これは最良の答えではありません。読者は改行をむちゃくちゃにするので、それらを維持するように注意する必要があります。
Jeffrey Blattman、2016年

173

Google-Collections / Guavaを使用している場合は、次のことができます。

InputStream stream = ...
String content = CharStreams.toString(new InputStreamReader(stream, Charsets.UTF_8));
Closeables.closeQuietly(stream);

の2番目のパラメーター(つまり、Charsets.UTF_8)InputStreamReaderは必要ないことに注意してください。ただし、エンコードがわかっている場合は、それを指定することをお勧めします(そうすべきです)。


2
@harschware:「java.io.InputStreamオブジェクトがある場合、そのオブジェクトをどのように処理して文字列を生成する必要がありますか?」その状況ではすでにストリームが存在していると想定しました。
桜庭

あなたの答えはあまりよく説明されておらず、無関係な変数がありました。user359996はあなたと同じことを言っていましたが、もっとはっきりしています。
ウロニム2009

2
グアバの場合は+1、入力ストリームのエンコーディングを指定しない場合は-1。例えば。新しいInputStreamReader(stream、 "UTF-8")
andras

@Chris Noldus一方、私のようにプロジェクトに既にグアバがいる人もいるので、このソリューションはSDKのみのバージョンよりもエレガントだと思います。
CorayThan 2013

@Vadzimその答えはこれと同じです-どちらもCharStreams.toStringを使用します
Tom

125

これは、Androidやその他のJVMに完全に適合する最高の純粋なJavaソリューションです。

このソリューションは驚くほどうまく機能します...それはシンプルで高速で、大小のストリームでもまったく同じように機能します!! (上記のベンチマークを参照してください。8番

public String readFullyAsString(InputStream inputStream, String encoding)
        throws IOException {
    return readFully(inputStream).toString(encoding);
}

public byte[] readFullyAsBytes(InputStream inputStream)
        throws IOException {
    return readFully(inputStream).toByteArray();
}

private ByteArrayOutputStream readFully(InputStream inputStream)
        throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int length = 0;
    while ((length = inputStream.read(buffer)) != -1) {
        baos.write(buffer, 0, length);
    }
    return baos;
}

4
エンタープライズJavaでのみ機能する他の回答と比較して、Androidでうまく機能します。
vortexwolf 2013年

短い文字列の場合、毎回 ".write"行にOutOfMemoryエラーが発生し、Androidでクラッシュしました。
アダム

エンコーディングを追加しました。補足として、コードにある元のreadFullyメソッドはStringを返さず、より汎用的な機能のためにbyte []を返します。エンコーディングで新しいString(...)を実装することは、APIを使用するの責任です!
TacB0sS 2013

2
クイックノート:これのメモリフットプリントはによって最大になります2*n。ここで、nはByteArrayInputStream自動拡張システムに従ってストリームのサイズです。
njzk2 14

3
メモリ使用量を不必要に2倍にします。これは、モバイルデバイスでは貴重です。InputStreamReaderを使用してStringReaderに追加することをお勧めします。バイトから文字への変換は、最後に一括ではなくオンザフライで行われます。
Oliv

84

完全を期すために、ここにJava 9ソリューションがあります

public static String toString(InputStream input) throws IOException {
    return new String(input.readAllBytes(), StandardCharsets.UTF_8);
}

readAllBytesそれはおそらくリリースに表示されるので、JDK 9メインのコードベースに現在あります。JDK 9スナップショットビルドを使用して、今すぐ試すことができます


このメソッドは、読み取り用に大量のメモリを割り当てませんか?byte[] buf = new byte[DEFAULT_BUFFER_SIZE];どこMAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;を与えるMAX_BUFFER_SIZE = 2147483639。グーグルはその約2.147 GBを言います。
Rekin

計算でエラーが発生しました。2GBです。コメントを編集しました。それで、たとえ4kbファイルのように読んだとしても、2GBのメモリを使用しますか?
Rekin

2
@ChristianHujer、最新のjdk8uコミットには表示されません。AFAIKの新しいメソッドは、メジャーリリースでのみJavaアップデートに導入されることはありません。
Tagir Valeev、2016

4
@ChristianHujer、問題はについてInputStreamではなくについてPathでした。InputStreamファイルだけではなく、多くの異なるソースから作成することができます。
Tagir Valeev 2016

5
これは1年前に書かれたので、更新するために、このメソッドが実際にパブリックリリースJDK 9にあることを確認します。さらに、エンコーディングが「ISO-Latin-1」の場合、Java 9文字列が現在使用されているため、これは非常に効率的です。byte[]すべての文字が最初の256コードポイントにある場合の実装。つまり、新しいString(byte []、 "ISO-Latin-1")は単純な配列のコピーになります。
クリトスキリアクー

66

使用する:

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;

public static String readInputStreamAsString(InputStream in)
    throws IOException {

    BufferedInputStream bis = new BufferedInputStream(in);
    ByteArrayOutputStream buf = new ByteArrayOutputStream();
    int result = bis.read();
    while(result != -1) {
      byte b = (byte)result;
      buf.write(b);
      result = bis.read();
    }
    return buf.toString();
}

@DanielDeLeónいいえ、ありません。それはBufferedInputStreamです。基礎となる読み取りは、一度に8192バイトです。
ローン侯爵

2
@EJP私はそれを使用してBufferedInputStream 一度に1バイトではなくバイト配列バッファに読み込むよりも遅いことがわかりました。例:4.56 MiBファイルの読み取り時の200ms vs 60ms。
jk7 2017年

ここで他の主要な問題を指摘した人がいないのは奇妙です(はい、バッファリングでもバイト単位でコンテンツを読み取るのは無駄です)。「デフォルトのエンコーディング」に依存していることに依存します。これはめったに良い方法ではありません。代わりに、エンコーディングを引数としてに渡してくださいbuf.toString()
StaxMan

@ jk7 4.56MBのファイルを読み取るのにかかる時間は非常に短いため、違いはそれほど大きくないはずです。
ローンの侯爵

63

これが、いくつかの実験の後に思いついた最もエレガントで純粋なJava(ライブラリなし)ソリューションです。

public static String fromStream(InputStream in) throws IOException
{
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    StringBuilder out = new StringBuilder();
    String newLine = System.getProperty("line.separator");
    String line;
    while ((line = reader.readLine()) != null) {
        out.append(line);
        out.append(newLine);
    }
    return out.toString();
}

8
@TorbenKohlmeier、リーダーとバッファを閉じる必要はありません。提供InputStreamされたものは、呼び出し側が閉じる必要があります。
Drew Noakes 2013年

7
CharSetを使用するInputStreamReaderには、より好ましいコンストラクタがあることを忘れないでください。
jontejj 2013年

7
なぜ人々は使い続けるのreadLineですか?ライン自体を使用しない場合、それは何が良いか(非常に遅いことを除いて?)
njzk2

4
行単位で読み取らないでください。1行が長すぎてヒープに収まらない場合はどうなりますか?
voho 2014

4
@ voho、1行が長い場合、その行と同じかそれ以上のサイズでなければならない戻り値をとにかく割り当てる方法はありません。それほど大きなファイルを扱う場合は、それらをストリーミングする必要があります。ただし、小さなテキストファイルをメモリにロードする使用例はたくさんあります。
ドリューノークス2014

55

私はここで14の異なる答えについてベンチマークを行いました(クレジットを提供しなかったため申し訳ありませんが、重複が多すぎます)。

結果は非常に驚くべきものです。Apache IOUtilsが最も遅く、ByteArrayOutputStream速いソリューションであるます。

したがって、最初にここが最善の方法です。

public String inputStreamToString(InputStream inputStream) throws IOException {
    try(ByteArrayOutputStream result = new ByteArrayOutputStream()) {
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) != -1) {
            result.write(buffer, 0, length);
        }

        return result.toString(UTF_8);
    }
}

20サイクルで20 MBのランダムバイトのベンチマーク結果

ミリ秒単位の時間

  • ByteArrayOutputStreamTest:194
  • NioStream:198
  • Java9ISTransferTo:201
  • Java9ISReadAllBytes:205
  • BufferedInputStreamVsByteArrayOutputStream:314
  • ApacheStringWriter2:574
  • GuavaCharStreams:589
  • ScannerReaderNoNextTest:614
  • スキャナーリーダー:633
  • ApacheStringWriter:1544
  • StreamApi:エラー
  • ParallelStreamApi:エラー
  • BufferReaderTest:エラー
  • InputStreamAndStringBuilder:エラー

ベンチマークソースコード

import com.google.common.io.CharStreams;
import org.apache.commons.io.IOUtils;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * Created by Ilya Gazman on 2/13/18.
 */
public class InputStreamToString {


    private static final String UTF_8 = "UTF-8";

    public static void main(String... args) {
        log("App started");
        byte[] bytes = new byte[1024 * 1024];
        new Random().nextBytes(bytes);
        log("Stream is ready\n");

        try {
            test(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void test(byte[] bytes) throws IOException {
        List<Stringify> tests = Arrays.asList(
                new ApacheStringWriter(),
                new ApacheStringWriter2(),
                new NioStream(),
                new ScannerReader(),
                new ScannerReaderNoNextTest(),
                new GuavaCharStreams(),
                new StreamApi(),
                new ParallelStreamApi(),
                new ByteArrayOutputStreamTest(),
                new BufferReaderTest(),
                new BufferedInputStreamVsByteArrayOutputStream(),
                new InputStreamAndStringBuilder(),
                new Java9ISTransferTo(),
                new Java9ISReadAllBytes()
        );

        String solution = new String(bytes, "UTF-8");

        for (Stringify test : tests) {
            try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) {
                String s = test.inputStreamToString(inputStream);
                if (!s.equals(solution)) {
                    log(test.name() + ": Error");
                    continue;
                }
            }
            long startTime = System.currentTimeMillis();
            for (int i = 0; i < 20; i++) {
                try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) {
                    test.inputStreamToString(inputStream);
                }
            }
            log(test.name() + ": " + (System.currentTimeMillis() - startTime));
        }
    }

    private static void log(String message) {
        System.out.println(message);
    }

    interface Stringify {
        String inputStreamToString(InputStream inputStream) throws IOException;

        default String name() {
            return this.getClass().getSimpleName();
        }
    }

    static class ApacheStringWriter implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            StringWriter writer = new StringWriter();
            IOUtils.copy(inputStream, writer, UTF_8);
            return writer.toString();
        }
    }

    static class ApacheStringWriter2 implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            return IOUtils.toString(inputStream, UTF_8);
        }
    }

    static class NioStream implements Stringify {

        @Override
        public String inputStreamToString(InputStream in) throws IOException {
            ReadableByteChannel channel = Channels.newChannel(in);
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 16);
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            WritableByteChannel outChannel = Channels.newChannel(bout);
            while (channel.read(byteBuffer) > 0 || byteBuffer.position() > 0) {
                byteBuffer.flip();  //make buffer ready for write
                outChannel.write(byteBuffer);
                byteBuffer.compact(); //make buffer ready for reading
            }
            channel.close();
            outChannel.close();
            return bout.toString(UTF_8);
        }
    }

    static class ScannerReader implements Stringify {

        @Override
        public String inputStreamToString(InputStream is) throws IOException {
            java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
            return s.hasNext() ? s.next() : "";
        }
    }

    static class ScannerReaderNoNextTest implements Stringify {

        @Override
        public String inputStreamToString(InputStream is) throws IOException {
            java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
            return s.next();
        }
    }

    static class GuavaCharStreams implements Stringify {

        @Override
        public String inputStreamToString(InputStream is) throws IOException {
            return CharStreams.toString(new InputStreamReader(
                    is, UTF_8));
        }
    }

    static class StreamApi implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            return new BufferedReader(new InputStreamReader(inputStream))
                    .lines().collect(Collectors.joining("\n"));
        }
    }

    static class ParallelStreamApi implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            return new BufferedReader(new InputStreamReader(inputStream)).lines()
                    .parallel().collect(Collectors.joining("\n"));
        }
    }

    static class ByteArrayOutputStreamTest implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            try(ByteArrayOutputStream result = new ByteArrayOutputStream()) {
                byte[] buffer = new byte[1024];
                int length;
                while ((length = inputStream.read(buffer)) != -1) {
                    result.write(buffer, 0, length);
                }

                return result.toString(UTF_8);
            }
        }
    }

    static class BufferReaderTest implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            String newLine = System.getProperty("line.separator");
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder result = new StringBuilder(UTF_8);
            String line;
            boolean flag = false;
            while ((line = reader.readLine()) != null) {
                result.append(flag ? newLine : "").append(line);
                flag = true;
            }
            return result.toString();
        }
    }

    static class BufferedInputStreamVsByteArrayOutputStream implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            BufferedInputStream bis = new BufferedInputStream(inputStream);
            ByteArrayOutputStream buf = new ByteArrayOutputStream();
            int result = bis.read();
            while (result != -1) {
                buf.write((byte) result);
                result = bis.read();
            }

            return buf.toString(UTF_8);
        }
    }

    static class InputStreamAndStringBuilder implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            int ch;
            StringBuilder sb = new StringBuilder(UTF_8);
            while ((ch = inputStream.read()) != -1)
                sb.append((char) ch);
            return sb.toString();
        }
    }

    static class Java9ISTransferTo implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            inputStream.transferTo(bos);
            return bos.toString(UTF_8);
        }
    }

    static class Java9ISReadAllBytes implements Stringify {

        @Override
        public String inputStreamToString(InputStream inputStream) throws IOException {
            return new String(inputStream.readAllBytes(), UTF_8);
        }
    }

}

Javaでベンチマークを作成することは簡単ではありません(特にJITのため)。ベンチマークのソースコードを読んだ後、上記の値は正確ではなく、誰もがそれらを信じて注意する必要があると確信しています。
Dalibor

@Daliborは、リンクではなく、主張に対してより多くの推論を提供する必要があります。
Ilya Gazman、

自分でベンチマークを作成するのは簡単ではないことは、よく知られている事実だと思います。それを知らない人のために、リンクがあります;)
Dalibor '29

@Dalibor私はおそらく最高ではないかもしれませんが、Javaベンチマークについては十分に理解しているため、特定の問題を指摘できない限り、あなたは誤解を招くだけであり、私はそれらの条件下であなたとの会話を続けることはありません。
Ilya Gazman、

ほとんど私はダリボルに同意します。「Javaベンチマークについて十分に理解している」とおっしゃいましたが、このアプローチのよく知られた問題を明らかに知らないまま、最も単純なアプローチを実装したようです。手始めに、この質問には、すべての記事を読む:stackoverflow.com/questions/504103/...
ダービッツ

41

Java 8のトリッ​​クをいくつか使用します。

public static String streamToString(final InputStream inputStream) throws Exception {
    // buffering optional
    try
    (
        final BufferedReader br
           = new BufferedReader(new InputStreamReader(inputStream))
    ) {
        // parallel optional
        return br.lines().parallel().collect(Collectors.joining("\n"));
    } catch (final IOException e) {
        throw new RuntimeException(e);
        // whatever.
    }
}

より簡潔である以外は、基本的に他のいくつかの回答と同じです。


5
それreturn nullが呼ばれることはありますか?どちらかbr.lines...を返すか、例外がスローされます。
Holloway 2014

3
@Khaled A Khunaifer:はい、かなり確かです...多分あなたはここを見る必要があります:docs.oracle.com/javase/tutorial/essential/exceptions/…。誤って編集したのは、「リソースを使用したトライ」ステートメントです。
jamp

11
なぜあなたparallel()はストリームを呼び出すのですか?
robinst 2015

4
これはを生じない正直なすべてのように、ソースストリームは、Windowsの改行コードを使用した場合、データのコピー\r\nに終わるだろうがに変換取得\n...
ルーカス

2
を使用System.lineSeparator()して、適切なプラットフォーム依存の行末を使用できます。
スティーブK

34

時間は常に重要なので、私はいくつかのタイミングテストを実行しました。

応答をString 3のさまざまな方法で取得しようとしました。(下に示された)
読みやすくするために、try / catchブロックをました。

コンテキストを与えるために、これは3つのアプローチすべての前のコードです。

   String response;
   String url = "www.blah.com/path?key=value";
   GetMethod method = new GetMethod(url);
   int status = client.executeMethod(method);

1)

 response = method.getResponseBodyAsString();

2)

InputStream resp = method.getResponseBodyAsStream();
InputStreamReader is=new InputStreamReader(resp);
BufferedReader br=new BufferedReader(is);
String read = null;
StringBuffer sb = new StringBuffer();
while((read = br.readLine()) != null) {
    sb.append(read);
}
response = sb.toString();

3)

InputStream iStream  = method.getResponseBodyAsStream();
StringWriter writer = new StringWriter();
IOUtils.copy(iStream, writer, "UTF-8");
response = writer.toString();

したがって、同じリクエスト/レスポンスデータを使用して各アプローチで500テストを実行した後の数値を次に示します。繰り返しますが、これらは私の発見であり、あなたの発見はまったく同じではないかもしれませんが、これらのアプローチの効率の違いを他の人に示すためにこれを書きました。

ランク:
アプローチ#1
アプローチ#3-#1
アプローチより2.6%遅い#2-#1より4.3%遅い

これらのアプローチはいずれも、応答を取得してそれから文字列を作成するための適切なソリューションです。


2
2)エラーが含まれています。文字列の最後に常に「null」が追加されます。これは、常に必要な手順を1つ追加するためです。とにかく性能は同じだと思います。これは機能するはずです:String read = null; StringBuffer sb = new StringBuffer(); while((read = br.readLine())!= null){sb.append(read); }
LukeSolar

GetMethodはorg.apache.commons.httpclientの一部であり、標準のJavaではないことに注意してください
jk7

アプローチ#2は、ファイルに多数の行がある場合に「\ n」を消費します。これは答えではありません
Ninja

33

Streamを使用したPure Javaソリューションは、Java 8以降で機能します。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;

// ...
public static String inputStreamToString(InputStream is) throws IOException {
    try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
        return br.lines().collect(Collectors.joining(System.lineSeparator()));
    }
}

ChristofferHammarströmが他の回答の下で述べたように、Charsetを明示的に指定する方が安全です。つまり、InputStreamReaderコンストラクタは次のように変更できます。

new InputStreamReader(is, Charset.forName("UTF-8"))

11
を行う代わりにCharset.forName("UTF-8")StandardCharsets.UTF_8(からjava.nio.charset)を使用します。
robinst 2015

26

以下はsampathの答えです。少し整理して、関数として表しています。

String streamToString(InputStream in) throws IOException {
  StringBuilder out = new StringBuilder();
  BufferedReader br = new BufferedReader(new InputStreamReader(in));
  for(String line = br.readLine(); line != null; line = br.readLine()) 
    out.append(line);
  br.close();
  return out.toString();
}

24

冒険したい場合は、ScalaとJavaを組み合わせて、次のようにすることができます。

scala.io.Source.fromInputStream(is).mkString("")

JavaとScalaのコードとライブラリを混在させることには利点があります。

詳細な説明はこちら:ScalaでInputStreamを文字列に変換する慣用的な方法


3
今日では、単にこれは罰金を動作します:Source.fromInputStream(...).mkString
KajMagnus

21

Commons IO(FileUtils / IOUtils / CopyUtils)を使用できない場合、BufferedReaderを使用してファイルを1行ずつ読み取る例を次に示します。

public class StringFromFile {
    public static void main(String[] args) /*throws UnsupportedEncodingException*/ {
        InputStream is = StringFromFile.class.getResourceAsStream("file.txt");
        BufferedReader br = new BufferedReader(new InputStreamReader(is/*, "UTF-8"*/));
        final int CHARS_PER_PAGE = 5000; //counting spaces
        StringBuilder builder = new StringBuilder(CHARS_PER_PAGE);
        try {
            for(String line=br.readLine(); line!=null; line=br.readLine()) {
                builder.append(line);
                builder.append('\n');
            }
        } 
        catch (IOException ignore) { }

        String text = builder.toString();
        System.out.println(text);
    }
}

または、生の速度が必要な場合は、Paul de Vriezeが提案したもののバリエーションを提案します(内部でStringBufferを使用するStringWriterの使用を避けます)。

public class StringFromFileFast {
    public static void main(String[] args) /*throws UnsupportedEncodingException*/ {
        InputStream is = StringFromFileFast.class.getResourceAsStream("file.txt");
        InputStreamReader input = new InputStreamReader(is/*, "UTF-8"*/);
        final int CHARS_PER_PAGE = 5000; //counting spaces
        final char[] buffer = new char[CHARS_PER_PAGE];
        StringBuilder output = new StringBuilder(CHARS_PER_PAGE);
        try {
            for(int read = input.read(buffer, 0, buffer.length);
                    read != -1;
                    read = input.read(buffer, 0, buffer.length)) {
                output.append(buffer, 0, read);
            }
        } catch (IOException ignore) { }

        String text = output.toString();
        System.out.println(text);
    }
}

コードを機能させるために、this.getClass()。getClassLoader()。getResourceAsStream()を使用する必要がありました(MavenプロジェクトでEclipseを使用)
2012年

19

これはいい理由です:

  • Charsetを安全に処理します。
  • 読み取りバッファサイズを制御します。
  • ビルダーの長さをプロビジョニングできますが、正確な値である必要はありません。
  • ライブラリの依存関係はありません。
  • Java 7以降用です。

どうやってするの?

public static String convertStreamToString(InputStream is) throws IOException {
   StringBuilder sb = new StringBuilder(2048); // Define a size if you have an idea of it.
   char[] read = new char[128]; // Your buffer size.
   try (InputStreamReader ir = new InputStreamReader(is, StandardCharsets.UTF_8)) {
     for (int i; -1 != (i = ir.read(read)); sb.append(read, 0, i));
   }
   return sb.toString();
}

JDK 9の場合

public static String inputStreamString(InputStream inputStream) throws IOException {
    try (inputStream) {
        return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
    }
}

1
catch (Throwable)これは、生産コードであれば、本当に空であってはなりません。
Christian Hujer 2016年

1
このキャッチに何を入れるか-スロー可能なステートメント?
アレックス

UTF-8の使用は通常妥当ですが、文字がそのようにエンコードされていると想定しないでください。
マーティン

18

これは、Apacheを実装したいがライブラリ全体を望まない人のための、org.apache.commons.io.IOUtils ソースコードからの回答です。

private static final int BUFFER_SIZE = 4 * 1024;

public static String inputStreamToString(InputStream inputStream, String charsetName)
        throws IOException {
    StringBuilder builder = new StringBuilder();
    InputStreamReader reader = new InputStreamReader(inputStream, charsetName);
    char[] buffer = new char[BUFFER_SIZE];
    int length;
    while ((length = reader.read(buffer)) != -1) {
        builder.append(buffer, 0, length);
    }
    return builder.toString();
}

18

ストリームリーダーを使用する場合は、最後にストリームを閉じるようにしてください

private String readStream(InputStream iStream) throws IOException {
    //build a Stream Reader, it can read char by char
    InputStreamReader iStreamReader = new InputStreamReader(iStream);
    //build a buffered Reader, so that i can read whole line at once
    BufferedReader bReader = new BufferedReader(iStreamReader);
    String line = null;
    StringBuilder builder = new StringBuilder();
    while((line = bReader.readLine()) != null) {  //Read till end
        builder.append(line);
        builder.append("\n"); // append new line to preserve lines
    }
    bReader.close();         //close all opened stuff
    iStreamReader.close();
    //iStream.close(); //EDIT: Let the creator of the stream close it!
                       // some readers may auto close the inner stream
    return builder.toString();
}

編集:JDK 7以降では、try-with-resourcesコンストラクトを使用できます。

/**
 * Reads the stream into a string
 * @param iStream the input stream
 * @return the string read from the stream
 * @throws IOException when an IO error occurs
 */
private String readStream(InputStream iStream) throws IOException {

    //Buffered reader allows us to read line by line
    try (BufferedReader bReader =
                 new BufferedReader(new InputStreamReader(iStream))){
        StringBuilder builder = new StringBuilder();
        String line;
        while((line = bReader.readLine()) != null) {  //Read till end
            builder.append(line);
            builder.append("\n"); // append new line to preserve lines
        }
        return builder.toString();
    }
}

2
ストリームを閉じることについてはあなたは正しいですが、ストリームを閉じる責任は通常、ストリームコンストラクターにあります(開始するものを終了します)。したがって、iStream発信者がを作成したので、実際には発信者によって閉じられるべきですiStream。さらに、ストリームを閉じるのはfinallyブロックで行う必要があります。Java7のtry-with-resourcesステートメントを使用することをお勧めします。あなたのコードでは、readLine()throws IOExceptionまたはbuilder.append()throwsしたOutOfMemoryErrorときに、ストリームは開いたままになります。
Christian Hujer 2016年

16

もう1つ、すべてのSpringユーザー向け:

import java.nio.charset.StandardCharsets;
import org.springframework.util.FileCopyUtils;

public String convertStreamToString(InputStream is) throws IOException { 
    return new String(FileCopyUtils.copyToByteArray(is), StandardCharsets.UTF_8);
}

のユーティリティメソッドはのユーティリティメソッドとorg.springframework.util.StreamUtils似ていますFileCopyUtilsが、終了してもストリームを開いたままにします。


16

Java 9でサポートされているjava.io.InputStream.transferTo(OutputStream)と、文字セット名を受け取るByteArrayOutputStream.toString(String)を使用します。

public static String gobble(InputStream in, String charsetName) throws IOException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    in.transferTo(bos);
    return bos.toString(charsetName);
}

あなたの場合、文字セット名に何を渡しましたか?
virsha 2017

1
@virsha InputStreamを提供したソースからそれを判断する必要があります。使用するエンコーディングがわからない場合、文字列を使用しても意味がないことに
jmehrens 2017

15

ここで変換するための完全な方法であるInputStreamString任意のサードパーティのライブラリを使用せずに。使用StringBuilderシングルスレッド環境のためのそれ以外の使用StringBuffer

public static String getString( InputStream is) throws IOException {
    int ch;
    StringBuilder sb = new StringBuilder();
    while((ch = is.read()) != -1)
        sb.append((char)ch);
    return sb.toString();
}

3
この方法では、エンコーディングは適用されません。したがって、InputStreamから受信したデータがUTF-8を使用してエンコードされているとしましょう。出力は正しくありません。これを修正するには、in = new InputStreamReader(inputStream)およびを使用できます(char)in.read()
Frederic Leitenberger 2014年

2
メモリも非効率的です。大規模な入力で以前にこれを使用してみましたが、StringBuilderがメモリ不足になりました
gengkev

1
char []バッファーを使用し、より効率的で文字セットを処理する同様の回答がもう1つあります。
Guillaume Perrot 2015

14

バイト配列バッファを使用してJDKのみを使用する方法は次のとおりです。これが実際にcommons-io IOUtils.copy()メソッドがすべて機能する方法です。の代わりにからコピーbyte[]するchar[]場合は、で置き換えることができます。ReaderInputStream

import java.io.ByteArrayOutputStream;
import java.io.InputStream;

...

InputStream is = ....
ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
byte[] buffer = new byte[8192];
int count = 0;
try {
  while ((count = is.read(buffer)) != -1) {
    baos.write(buffer, 0, count);
  }
}
finally {
  try {
    is.close();
  }
  catch (Exception ignore) {
  }
}

String charset = "UTF-8";
String inputStreamAsString = baos.toString(charset);

1
達成しようとしていることについて説明してください。
Ragunathジャワハー

14

Kotlinユーザーは単に次のことを行います。

println(InputStreamReader(is).readText())

一方

readText()

Kotlin標準ライブラリの組み込み拡張メソッドです。


ストリームを閉じないため、これは実際には正しくありません。お勧めしis.bufferedReader().use { it.readText() }ます。
最大

9

JDKで最も簡単な方法は、次のコードスニペットを使用することです。

String convertToString(InputStream in){
    String resource = new Scanner(in).useDelimiter("\\Z").next();
    return resource;
}

7

これが私のJava 8ベースのソリューションで、新しいStream APIを使用してからすべての行を収集しますInputStream

public static String toString(InputStream inputStream) {
    BufferedReader reader = new BufferedReader(
        new InputStreamReader(inputStream));
    return reader.lines().collect(Collectors.joining(
        System.getProperty("line.separator")));
}

1
以前に投稿されたすべての回答を実際に読んだわけではないようです。ストリームAPIバージョンはすでに少なくとも2回ここにありました。
Tagir Valeev

私はすべての解決策を見てきましたが、適切なものは見つかりませんでした。短い説明のある2行が正確に表示されていることがわかります。たとえば、他のソリューションのtry-catch-blockは決して使用されません。しかし、あなたは正しいです。非常に多くの回答を得て、私は高速スキップ読み取りモードに切り替えました... :-)
ChristianRädelSep

1
元のファイルを読み取るのではなく、ファイルの末尾がOSの末尾に変換され、ファイルの内容が変更される可能性があります。
Christian Hujer 2016年

7

に関してはreduceconcatJava 8では次のように表現できます。

String fromFile = new BufferedReader(new   
InputStreamReader(inputStream)).lines().reduce(String::concat).get();

1
非常に遅くなります。
Tagir Valeev 2016年

興味深いのはなぜですか?詳しく説明してもらえますか?
libnull-dev 2016

1
StringBuilderを使用する代わりにループ内で文字列を連結することが悪い考えである理由を知らないのですか?
Tagir Valeev

あなたが正しいです。StringBuilderより効率的かもしれません。チェックしますが、私のポイントは、immutableを使用したより機能的なアプローチを示すことでしたString
libnull-dev 2016

機能的なアプローチはクールですが、通常は非常に非効率的です。
Lluis Martinez

4

ストリームを閉じてもIOExceptionをスローするJDK 7/8回答:

StringBuilder build = new StringBuilder();
byte[] buf = new byte[1024];
int length;
try (InputStream is = getInputStream()) {
  while ((length = is.read(buf)) != -1) {
    build.append(new String(buf, 0, length));
  }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.