前言
Java
中的InputSteam
是程序从其中读取数据, OutputSteam
是程序可以往里面写入数据。
如果我们有在项目中读取数据库的记录, 在转存成Excel文件, 再把文件转存到OSS中。
生成Excel使用的是阿里的EasyExcel
。 他支持Output的方式写出文件内容。 而我使用的OSS的Client却只支持InputSteam
的方式传入内容。
这就需要我把excel的数据流从InputStream
传输到OutputStream
中了。 这就要用到JAVA中的管道流功能了。
用法
下面是用法示例:
//需要注意顺序, PipedOutputStream是管道的输入端, 需要先关闭, 这样输出端就知道管道结束了,才能正常结束
try (PipedOutputStream pipedOutputStream = new PipedOutputStream();
PipedInputStream pipedInputStream = new PipedInputStream(pipedOutputStream)) {
ThreadUtil.execute(()->{
//从数据库中读取内容, 忽略写法
List<Object> data = ......
//写入数据到output中,
pipedOutputStream.write(JSON.toJSONBytes(data));
//一定要调用这个方法, 不然input端不知道啥时候管道结束,就会一直堵塞等待
pipedOutputStream.close();
});
//从input中读取数据上传到OSS中
ossClient.putObject(path, pipedInputStream)
} catch (Exception e) {
throw new BusinessRuntimeException("接入日志文件下载异常", e);
}
- 注意管道的关闭顺序, 需要先关闭输入端,这样读取端才能结束阻塞。
- 两个流需要在两个线程中,如果在一个线程中,如果先写入数据,不写入结束就不会往下继续执行, 这就失去了管道流的意义。
总结
管道流正确的用法,是用于线程之间互相通信的, 上面的例子是由于EasyExcel的API设计不太合理的, EasyExcel使用不灵活, 所以没办法才使用管道流来把EasyExcel与OSSClient关联起来。