我有一些来自不同文件的数据流。格式如下:
Stream<String> linesModifiedAndAppendedFromVariousFiles=getLines();
但是,我需要将其提供给接受InputStream或Reader作为参数的库方法。
如何将Java 8流馈送到InputStream或类型的Reader中?
P.S:这不是关于将java.util.streams.Stream封装在InputStream周围。我正在寻找的是相反的方式。
答案 0 :(得分:2)
您可以使用PipedReader和PipedWriter来做到这一点。
PipedReader reader = new PipedReader();
Runnable feeder = new Runnable() {
@Override
public void run() {
try (PipedWriter writer = new PipedWriter(reader)) {
linesModifiedAndAppendedFromVariousFiles.forEachOrdered(line -> {
try {
writer.write(line);
writer.write('\n');
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
new Thread(feeder).start();
someLibraryMethod.consumeReader(reader);
答案 1 :(得分:1)
java.util.Stream
从概念上讲可能是无止境的,不可逆的(例如,一旦经过一个条目,您将无法返回它),这可能会允许您并行处理它。至关重要的是,序列中的“东西”完全可以是任何东西。例如,您可以拥有一个Color对象流。
java.io.InputStream
从概念上讲是潜在的无穷无尽,不可逆的字节序列。
这两件事根本不一样。
但是,如果您有专门的字节流,则可以将其转换为输入流。您只需选择不使用Stream固有的并行化选项,然后这两件事就会变成同一件事。但是,如果您拥有不小于字节的任何内容流,则必须提出“映射”。
假设您有一个字符串对象流。假设这是英文的前4个数字(例如:Arrays.asList("one", "two", "three", "four").stream()
)的流。
您如何将这个字符串流映射为字节流?一种策略是使用UTF-8编码将字符串呈现为字节,并使用0字符作为分隔符。换句话说,您想要与以下假设相同的结果:new ByteArrayInputStream(new String("one\0two\0three\0four").getBytes(StandardCharsets.UTF_8))
。
可以想象一个函数,它接受Stream<Byte>
并将其转换为InputStream。但是,Stream<Byte>
是一个非常低效的概念。人们还可以想象一个函数,它包含一个Stream<T>
和一个将T
映射到byte[]
的映射函数,以及一个分隔符常量(或生成值的函数),该分隔符常量会产生分隔符。对于上面的示例,类似:
toInputStream(oneTwoThreeFour, str -> str.getBytes(StandardCharsets.UTF_8), "\0");
据我所知,在核心库中也不存在,在诸如番石榴之类的地方也不存在。但是编写它应该很简单。也许只有一页代码的价值。
答案 2 :(得分:0)
读取字节流:
PipedInputStream inputStream = new PipedInputStream();
Thread infinitInputStreamSupplier = infinitInputStreamSupplierThread(inputStream);
infinitInputStreamSupplier.start();
//consume input stream here...
infinitInputStreamSupplier.interrupt();
以下是生成输入流的方法
private Thread infinitInputStreamSupplierThread(final PipedInputStream inputStream) {
return new Thread(() -> {
try (PipedOutputStream outputStream = new PipedOutputStream(inputStream)) {
Stream<byte[]> infiniteStream = Stream.generate(randomByteSupplier());
infiniteStream.forEachOrdered(bytes -> {
try {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
});
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
private Supplier<byte[]> randomByteSupplier() {
return () -> {
byte[] bytes = new byte[100];
new Random().nextBytes(bytes);
return bytes;
};
}