如何将多个不同的InputStream链接到一个InputStream中
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将多个不同的InputStream链接到一个InputStream中相关的知识,希望对你有一定的参考价值。
我想知道是否有任何想法的方法将多个InputStream链接到Java(或Scala)中的一个连续的InputStream中。
我需要它是解析我从FTP服务器通过网络加载的平面文件。我想要做的是获取文件[1..N],打开流然后将它们组合成一个流。所以当file1结束时,我想从file2开始读取,依此类推,直到我到达fileN的末尾。
我需要按特定的顺序读取这些文件,数据来自遗留系统,该系统在barches中生成文件,因此一个数据依赖于另一个文件中的数据,但我想将它们作为一个连续流来处理,以简化我的域逻辑接口。
我四处搜索并找到了PipedInputStream,但我并不认为这是我需要的。一个例子会有所帮助。
它就在JDK中!引用JavaDoc of SequenceInputStream
:
SequenceInputStream
表示其他输入流的逻辑串联。它从一个有序的输入流集合开始,从第一个读取到文件结束,然后从第二个读取,依此类推,直到最后一个包含的输入流到达文件末尾。
你想连接任意数量的InputStream
s,而SequenceInputStream
只接受两个。但由于SequenceInputStream
也是一个InputStream
,你可以递归地应用它(嵌套它们):
new SequenceInputStream(
new SequenceInputStream(
new SequenceInputStream(file1, file2),
file3
),
file4
);
......你明白了。
See also
这是使用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)
}
}
有了这个,我可以按如下方式进行流测序
val mergedStream = stream1++stream2++stream3
甚至
val streamList = //some arbitrary-length list of streams, non-empty
val mergedStream = streamList.reduceLeft(_++_)
另一种解决方案:首先创建输入流列表,然后创建输入流序列:
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)))
这是一个使用Vector的更优雅的解决方案,这是专门为android而使用任何Java的矢量
AssetManager am = getAssets();
Vector v = new Vector(Constant.PAGES);
for (int i = 0; i < Constant.PAGES; i++) {
String fileName = "file" + i + ".txt";
InputStream is = am.open(fileName);
v.add(is);
}
Enumeration e = v.elements();
SequenceInputStream sis = new SequenceInputStream(e);
InputStreamReader isr = new InputStreamReader(sis);
Scanner scanner = new Scanner(isr); // or use bufferedReader
这是一个简单的Scala版本,它连接了一个Iterator[InputStream]
:
import java.io.{InputStream, SequenceInputStream}
import scala.collection.JavaConverters._
def concatInputStreams(streams: Iterator[InputStream]): InputStream =
new SequenceInputStream(streams.asJavaEnumeration)
以上是关于如何将多个不同的InputStream链接到一个InputStream中的主要内容,如果未能解决你的问题,请参考以下文章
将多个自定义 UITableViewCell 链接到单个 xib