PipedInputStream 和 PipedOutputStream 设计用来解决跨线程的字节数据传输。它们总是成对出现的,而在使用上,也只能 工作在两个不同的线程上,在一个线程里使用管道输…
一、前言
PipedInputStream 和 PipedOutputStream 设计用来解决跨线程的字节数据传输。它们总是成对出现的,而在使用上,也只能 工作在两个不同的线程上,在一个线程里使用管道输入和输出流可能会造成死锁。网上有很多介绍这两个存在于 io 包下的 API。却几乎 找不到一个写 PipedInputStream 的使用场景的,所以本文结合实际业务,来聊一聊 PipedInputStream 的应用。
1.1 原理简介
我们知道,输出流写数据,输入流读数据,PipedInputStream 和 PipedOutputStream 也一样,在 PipedOutputStream 的内部有一个 PipedInputStream 类型的sink
属性,用来接收 PipedOutputStream 写入的字节数据。而在 PipedInputStream 内部,定义了一个默认为1024
大小的字节数组buffer
,作为数据传输的缓冲区。这样一来,就变成了 PipedOutputStream 往
里写数据,当写满了
1 | |
读取数据,会返回 -1。标识了数据读完到达了流的末尾了。
1.2 使用场景概述
1 | |
main
1 | |
简单的理解了原理后,写了一个简单的演示 demo,但是 demo 不能说明啥问题,那从一个线程传输字节到另一个线程到底有啥用呢?博主,简单的的总结下:通过 java 应用生成文件,然后需要将文件上传到云端的场景,都可以用管道流。相同的业务场景,在没了解管道流之前,都是先将文件写入到本地磁盘,然后从文件磁盘读出来上传到云盘。了解这个后,可以脑补出很多的业务场景了(真实业务场景,都是博主遇到过的),比如:
1 | |
List
try {
//文件生成
ExcelUtils.getInstance().exportObjects2Excel(database,out);
1 | |
//文件上传
ossClient.putObject(“test”,”test.xlsx”,in);
1 | |
案例二:xml 文件数据传输
此类需求常见于和银行以及金融机构对接时,要求上报一些 xml 格式的数据,给到指定的 ftp、或是 oss 的某个目录下,用于对账。其实从文件上传的场景来说,和上面的案例一是一样。也是我总结的那样,在内存里生成文件,然后上传到云端,伪代码如下:
try(GZIPOutputStream gzipOut = new GZIPOutputStream(out)) {
Marshaller marshaller = JAXBContext.newInstance(Object.class).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(database,gzipOut);
} catch (IOException | JAXBException e) {
}
ossClient.putObject(“test”,”test.xml.gz”,in);
}
1 | |
本文标题: java管道流PipedInputStream的应用
发布时间: 2023年01月16日 00:00
最后更新: 2026年09月16日 05:40
原始链接: https://haoxiang.eu.org/ec4ba199/
版权声明: 本文著作权归作者所有,均采用CC BY-NC-SA 4.0许可协议,转载请注明出处!

