2016-09-21 8 views
1

私はStream<String>を受け取る関数を持っています。このストリームは、ファイル内の行を表します(Files.lines(somePath)によって呼び出されます)。私は、ファイルシステム上の複数の物理ファイルにストリームを変換する必要があり文字列のストリームをグループ化された文字列リストに変換する効率的な方法

 
__HEADER__ # for file 1 
data 
more data 
... 
__HEADER__ # file 2 starts here 
some more data... 
... 

:ファイル自体は、単一のファイルに、実際にこのような何か多くのファイルを連結したものです。私は単純なアプローチ、の線に沿って何かしようとした

String allLinesJoined = lineStream.collect(Collectors.joining()); 
// This solution seems to get stuck on the line above^
String files[] = allLinesJoined.split("__HEADER__"); 
for (fileStr : files) 
{ 
    // This function will write each fileStr to a separate file 
    // (filename is determined by contents of fileStr) 
    writeToPhysicalFile(fileStr); 
} 

しかし、入力ファイルは、およそ〜300メガバイトである(より大きな得ることができる)、この溶液を最初にはまり込むように見えますライン。もし私がもっと記憶を持っていたら、それは完了するでしょう...?

スタートポイントがStream<String>の場合、これを行うより良い方法がありますか、このコードをストリーミングAPIを使用せずに1行ずつ読み込むことができるように変更する必要がありますか?

(行の順序は、これらのファイルのコンテキストでは、問題ありません)

TL; DR

私は多くの小さなファイルにしてStream<String>として表さ一つの大きなファイルを有効にする必要があります。すべての小さなファイルは__HEADER__で始まり、すべての行は次のファイルである__HEADER__まで続きます。現在のライブラリはストリームを使用してファイルを提供しますが、ストリームでこれを実行しようとする価値がありますか、ライブラリを変更して非ストリーム機能を提供すると、私の人生は楽になりますか?

+0

があなたの最終目標が何であるかに関しては、いくつかの混乱があるかもしれません(少なくとも私は混乱しています)。私は問題は理解していますが、望ましい解決策は理解していません。 –

+1

@ChrisThompson:私もそれを理解しました。 – FrustratedWithFormsDesigner

+0

ストリームはこれに合わせて設計されていません。それらは、ストリームが個別にチャンクされる方法を気にしない操作のために設計されています。 –

答えて

2

それはストリームのアイデアを全滅させます。

てみますforeach():競合回答に基づいて

Stream<String> lineStream = Files.lines(Paths.get("your_file")); 

    lineStream.forEachOrdered((s) -> { 
     if ("HEADER".equals(s)) { 
      // create new file 
     } 
     else { 
      // append to this file 
     } 
    }); 
+0

はい、ストリームのアイデアではうまくいきませんが、これに基づいて非常にうまく動作するものを手に入れることができましたし、基礎となるコードを書き直すよりも速く、非常にうまく機能します。 :) – FrustratedWithFormsDesigner

+1

私はあなたを個人的に、いかなる方法でも批判しません!それぞれがすべての解を知っていれば、まずはStackOverflowがありません。 –

関連する問題