流 <Object> 到 InputStream

Stream<Object> to InputStream

如何转换类型 Stream<Object> 变成 InputStream?目前,我获取迭代器并遍历所有数据,将其转换为 byteArray 并将其添加到 inputStream:

 ByteArrayOutputStream bos = new ByteArrayOutputStream();
 ObjectOutputStream oos = new ObjectOutputStream(bos);

 Iterator<MyType> myItr = MyObject.getStream().iterator();

 while (myItr.hasNext()) {   

       oos.writeObject(myItr.next().toString()
         .getBytes(StandardCharsets.UTF_8));
   }
   oos.flush();
   oos.close();

   InputStream is = new ByteArrayInputStream(bao.toByteArray());

这样做的开销是多少?如果我的流包含 1 TB 的数据,我是否会将 1 TB 的数据吸入内存?有没有更好的方法来实现这个?

您应该能够使用管道将 OutputStream 转换为 InputStream

PipedOutputStream pos = new PipedOutputStream();
InputStream is = new PipedInputStream(pos);

new Thread(() -> {
    try (ObjectOutputStream oos = new ObjectOutputStream(pos)) {
        Iterator<MyType> myItr = MyObject.getStream().iterator();
        while (myItr.hasNext()) {
            oos.writeObject(myItr.next().toString()
                .getBytes(StandardCharsets.UTF_8));
        }
    } catch (IOException e) {
        // handle closed pipe etc.
    }
}).start();

灵感来自 this answer

这对你有用吗?

https://gist.github.com/stephenhand/292cdd8bba7a452d83c51c00d9ef113c

这是一个 InputStream 实现,将 Stream<byte[]> 作为输入数据。您只需要 .map() 您的任意对象到字节数组,但是您希望每个对象都表示为字节。

它仅在读取 InputStream 时调用 Stream 上的终端操作,当消费者读取更多 InputStream 时将对象从 Stream 中拉出,因此它从不将整个集合加载到内存中