65

Java(またはScala)で複数のInputStreamを1つの継続的なInputStreamにチェーンする慣用的な方法があるかどうか疑問に思っています。

私が必要とするのは、FTP サーバーからネットワーク経由でロードするフラット ファイルを解析することです。私がやりたいことは、ファイル[1..N]を取り、ストリームを開き、それらを1つのストリームに結合することです。そのため、file1 が終了したら、file2 などから読み取りを開始し、fileN の最後に到達するまで続けます。

これらのファイルを特定の順序で読み取る必要があります。データはバーチ形式でファイルを生成するレガシー システムから取得されるため、1 つのデータは別のファイルのデータに依存しますが、ドメイン ロジック インターフェイスを簡素化するために、それらを 1 つの継続的なストリームとして処理したいと考えています。 .

私は周りを検索してPipedInputStreamを見つけましたが、それが必要なものであるとは確信していません。例が役に立ちます。

4

5 に答える 5

106

それはJDKにあります!の JavaDoc をSequenceInputStream引用:

ASequenceInputStreamは、他の入力ストリームの論理連結を表します。入力ストリームの順序付けられたコレクションから開始し、最初のストリームからファイルの終わりに達するまで読み取り、その後、2 番目のストリームから読み取り、というように、含まれている最後の入力ストリームでファイルの終わりに達するまで続きます。

2つだけを受け入れInputStreamながら、任意の数の を連結したい。SequenceInputStreamしかし、SequenceInputStreamInputStream再帰的に適用できる (入れ子にする) こともできるためです。

new SequenceInputStream(
    new SequenceInputStream(
        new SequenceInputStream(file1, file2),
        file3
    ),
    file4
);

…お分かりですね。

こちらもご覧ください

于 2013-01-12T16:08:04.670 に答える
16

これは、Tomasz Nurkiewicz の回答が示すように、Java では簡単な SequencedInputStream を使用して行われます。最近、あるプロジェクトでこれを繰り返し行う必要があったため、「ライブラリをポン引きする」パターンを使用して Scala の利点を追加しました。

object StreamUtils {
  implicit def toRichInputStream(str: InputStream) = new RichInputStream(str)

  class RichInputStream(str: InputStream) {
// a bunch of other handy Stream functionality, deleted

    def ++(str2: InputStream): InputStream = new SequenceInputStream(str, str2)
  }
}

これで、次のようにストリーム シーケンスを実行できます

val mergedStream = stream1++stream2++stream3

あるいは

val streamList = //some arbitrary-length list of streams, non-empty
val mergedStream = streamList.reduceLeft(_++_)
于 2013-01-12T16:34:38.220 に答える
15

別の解決策: 最初に入力ストリームのリストを作成し、次に入力ストリームのシーケンスを作成します。

List<InputStream> iss = Files.list(Paths.get("/your/path"))
        .filter(Files::isRegularFile)
        .map(f -> {
            try {
                return new FileInputStream(f.toString());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }).collect(Collectors.toList());

new SequenceInputStream(Collections.enumeration(iss)))
于 2016-07-15T15:13:15.670 に答える