通过Akka / Spring流从InputStream发送数据

时间:2017-02-25 13:52:31

标签: spring akka inputstream reactive-programming akka-stream

以下是我之前的问题:Send big file over reactive stream

我已经设法使用FileIO.fromPath(Paths.get(file.toURI()))通过Akka流发送文件,它工作正常。但是,我想在发送之前压缩和加密文件。我创建了方法,打开FileInputStream,通过压缩流然后通过加密流路由它,现在我想用Akka流将它引导到套接字。

档案 - > FileInputStream - > CompressedInputStream - > EncryptedInputStream - ?> Spring / Akka流

关键是,我可以在按块查看块的同时对文件进行压缩/加密(我没有在磁盘上创建其他文件),我看不出如何发送InputStream(压缩和加密)在Akka / Spring流上(Spring流,我指的是项目Reactor API下的Akka流)。

问题是:如何在不将整个压缩/加密文件保存到磁盘的情况下压缩,加密和发送文件?

2 个答案:

答案 0 :(得分:4)

我(意外地)发现:StreamConverters.fromInputStream!

http://doc.akka.io/docs/akka/2.4.17/java/stream/stages-overview.html#fromInputStream

答案 1 :(得分:3)

实际上,有一个专门用于处理输入流等资源的源。它被称为Source.unfoldResource

Source<ByteString, NotUsed> source = Source.unfoldResource(
    () -> prepareEncryptedStream(),
    is -> readChunk(is, 4096),
    InputStream::close
);

Optional<ByteString> readChunk(InputStream is, int size) throws IOException {
    byte[] data = new byte[size];
    int read = is.read(data);
    if (read < 0) {
        return Optional.empty();
    }
    return Optional.of(ByteString.fromArray(data, 0, read));
}

InputStream prepareEncryptedStream() { ... }

此处prepareCompressedFile()是一种方法,应该返回您想要创建反应流的加密流,readChunk()是一种从{{1}读取ByteString的便捷方法指定大小。

如果您可以将压缩和加密例程表示为InputStream函数,那么您并不需要这样做;您需要做的就是将这些例程传递给ByteString -> ByteString流程:

map()