如何将多个不同的输入流链接到一个输入流中另请参见

2022-08-31 15:08:05

我想知道是否有任何意识形态的方法可以将多个输入流链接到Java(或Scala)中的一个连续的输入流中。

我需要它来解析我从FTP服务器通过网络加载的平面文件。我想做的是获取file[1..N],打开流,然后将它们组合成一个流。因此,当 file1 结束时,我想开始从 file2 读取,依此类推,直到我到达 fileN 的末尾。

我需要以特定的顺序读取这些文件,数据来自一个以barches形式生成文件的遗留系统,因此一个文件中的数据依赖于另一个文件中的数据,但我想将它们作为一个连续流来处理,以简化我的域逻辑接口。

我四处搜索并找到了PipedInputStream,但我并不肯定这是我所需要的。举个例子会有所帮助。


答案 1

它就在JDK中!引用 SequenceInputStream 的 JavaDoc

A 表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流读取,直到到达文件末尾,然后从第二个输入流读取,依此类推,直到在最后一个包含的输入流上到达文件末尾。SequenceInputStream

您希望连接任意数量的 s,而只接受两个。但是,由于也是一个,您可以递归地应用它(嵌套它们):InputStreamSequenceInputStreamSequenceInputStreamInputStream

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

...你明白了。

另请参见


答案 2

这是使用SequendInputStream完成的,这在Java中很简单,正如Tomasz Nurkiewicz的答案所示。我最近不得不在一个项目中反复这样做,所以我通过“皮条客我的库”模式添加了一些Scala-y的优点。

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(_++_)

推荐