为什么80%的码农都做不了架构师?>>>
问题
在完成Spring从MongoDB中下载文件之GridFS之后,现在需要在ZK7.0.3的ViewModel中下载该文件。
思路
先从MongoDB获取到OutputStream
,以及把OutputStream
转化为ZK的Filedownload能够使用的InputStream
进行文件下载。
实现
导入Filedownload
import org.zkoss.zul.Filedownload;
ViewModel
String fileId = "5602de6e5d8bba0d6f2e45e4";
// 从Mongod中查找出一个文件,注意这里返回为com.mongodb.client.gridfs.model.GridFSFile类
GridFSFile gridFsdbFile = operations.findOne(new Query(Criteria.where("_id").is(fileId)));
if (gridFsdbFile != null) {// mongo-java-driver3.x以上的版本就变成了这种方式获取GridFSBucket bucket = GridFSBuckets.create(mongoDbFactory.getDb());ByteArrayOutputStream baos = new ByteArrayOutputStream();// 获取Mongodb中文件的缓存输出流bucket.downloadToStream(gridFsdbFile.getId(), baos);Document meteData = gridFsdbFile.getMetadata();// 将OutputStream缓存流转化为InputStream缓存流使用ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());// 下载文件if(meteData != null) {Filedownload.save(bais, meteData.get("contentType").toString(), gridFsdbFile.getFilename());} else {Filedownload.save(bais, null, gridFsdbFile.getFilename());}
}
**Note:**这里主要的问题其实转化为Java的流转化了。JavaOutputStream流转化InputStream流方式很多,主要三种:
- 使用缓存流转化
- 使用管道流转化
- 使用循环缓存流转化
缓存流:
ByteArrayOutputStream out = new ByteArrayOutputStream();
class1.putDataOnOutputStream(out);
class2.processDataFromInputStream(new ByteArrayInputStream(out.toByteArray())
);
管道流
PipedInputStream in = new PipedInputStream();
PipedOUtputStream out = new PipedOutputStream(in);
new Thread(new Runnable(){public void run(){class1.putDataOnOutputStream(out);}}
).start();
class2.processDataFromInputStream(in);
循环流
// 多线程方式
CircularByteBuffer cbb = new CircularByteBuffer();
new Thread(new Runnable(){public void run(){class1.putDataOnOutputStream(cbb.getOutputStream());}}
).start();
class2.processDataFromInputStream(cbb.getInputStream());
// 单线程方式
// buffer all data in a circular buffer of infinite size
CircularByteBuffer cbb = new CircularByteBuffer(CircularByteBuffer.INFINITE_SIZE);
class1.putDataOnOutputStream(cbb.getOutputStream());
class2.processDataFromInputStream(cbb.getInputStream());
总结
主要是使用ZK的Filedownload进行文件下载,但是ZK的Filedownload需要InputStream支持,所以,就涉及到了OutputStream转InputStream操作。
参考: Convert a Java OutputStream to an InputStream Class Filedownload