2016-12-25 5 views
-2

素敵なtoStringメソッドを使ってカスタムオブジェクトのストリームをファイルに1行ずつ書き込もうとしています。私はこれまで持っていることはこれです:ファイルへのオブジェクトのストリームの書き込み

private static void writeToFile(Set<Article> articles, Charset cs, Path path) throws IOException { 

    try(Writer w = 
      new BufferedWriter(
      new OutputStreamWriter(
      new FileOutputStream(path.toFile()), cs))) { 

     articles.stream().map(Article::toString).forEach(w::write); 

    } catch(IOException e) {} 

私はこの例外をキャッチしていますので、奇妙なワット::書き込み、上のエラー未処理のIOExceptionを取得していますか?

他の点では、これらのオブジェクトを1行ずつ書き込むことは可能ですか?

+0

の可能性のある重複した[Javaの8:?どのように私はストリームのメソッドを投げる例外では動作しないが、(http://stackoverflow.com/questions/23548589/java-8ストリーム内で例外をスローするメソッドを使用すると、 – Natecat

+0

も同様です。 – zwiebl

+0

実際には非常に近いですが、類似点は隠されています。 – HTNW

答えて

2

foreachConsumer<? super E>となります。EStreamの要素のタイプです。 Consumer<T>::acceptの署名は、それがどんなチェック例外をスローしませんどのように注意

void accept(T t) 

です。あなたが.foreach(w::write)を行うときにはない1(Consumer<T>::accept)として、例外(Writer::write)をスローするメソッドを使用しようとしているので、

さて、Writer::writeがチェックIOExceptionを投げるんので、コンパイラは文句を言います。代わりに、ストリームからの書き込みで、あなたがメモリに全体Stringを構築することができ、その後、一度にすべてを書く

articles.stream().map(Article::toString).forEach(str -> { 
    try { 
     w.write(str + System.lineSeparator()); // Add a newline to each string. 
    } catch(IOException e) { 
     ... 
    } 
}); 

注:この問題を解決するためには、foreach自体で例外を処理する必要があります。

String data = articles.stream().map(Article::toString).map(str -> str + System.lineSeparator()).reduce("", (acc, str) -> str + acc) 
w.write(data.substring(0, data.length()-1)); // Drop last newline 
3

PrintWriterその方法はIOExceptionをスローしていないとして、このような場合に便利です。またprint(Object)オーバーロードがあり、オブジェクトをtoStringメソッドで文字列に変換します。それは代わりに、代わりに実際のCharsetオブジェクトのPathと文字セット名のFileを取るとして(実際にそれがtoStringに委任する前に、ヌルを処理するString.valueOf呼び出します。)

残念ながらPrintWriterは、やや古風なAPIです。しかし、変換はそれほど大きなものではありません。

オブジェクトを文字列に変換するために中間のmap呼び出しが必要ないため、コレクションで直接forEachを呼び出すだけで十分です。

ここで生成されたコードです:

static void writeToFile(Set<Article> articles, Charset cs, Path path) throws IOException { 
    try (PrintWriter pw = new PrintWriter(path.toFile(), cs.name())) { 
     articles.forEach(pw::println); 
    } 
} 
関連する問題