如何将多个不同的InputStream链接到一个InputStream中

Mag*_*nus 59 java io scala inputstream

我想知道是否有任何想法的方法将多个InputStream链接到Java(或Scala)中的一个连续的InputStream中.

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

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

我四处搜索并找到了PipedInputStream,但我并不认为这是我需要的.一个例子会有所帮助.

Tom*_*icz 95

它就在JDK中!引用JavaDocSequenceInputStream:

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

你想连接任意数量的InputStreams而SequenceInputStream只接受两个.但由于SequenceInputStream也是InputStream可以递归(嵌套他们)应用它:

new SequenceInputStream(
    new SequenceInputStream(
        new SequenceInputStream(file1, file2),
        file3
    ),
    file4
);
Run Code Online (Sandbox Code Playgroud)

......你明白了.

也可以看看

  • 如果我使用这种技术链接数百个输入流,它们是否有任何问题? (6认同)
  • SequenceInputStream构造函数也接受Enumeration,因此您不必进行嵌套. (4认同)
  • 卫生署!今天谷歌搜索时,我的关键字一定非常糟糕.因为我给了它一个很好的谷歌搜索.我想我真的不能成为第一个需要这个的人,谢谢! (3认同)

Dav*_*ith 15

这是使用SequencedInputStream完成的,这在Java中是直截了当的,正如Tomasz Nurkiewicz的答案所示.我最近不得不在一个项目中反复这样做,所以我通过"pimp my library"模式添加了一些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)
  }
}
Run Code Online (Sandbox Code Playgroud)

有了这个,我可以按如下方式进行流测序

val mergedStream = stream1++stream2++stream3
Run Code Online (Sandbox Code Playgroud)

甚至

val streamList = //some arbitrary-length list of streams, non-empty
val mergedStream = streamList.reduceLeft(_++_)
Run Code Online (Sandbox Code Playgroud)


fre*_*dev 12

另一种解决方案:首先创建输入流列表,然后创建输入流序列:

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)))
Run Code Online (Sandbox Code Playgroud)