ZK7.0.3中從MongoDB下載文件

問題

在完成Spring從MongoDB中下載文件之GridFS以後,如今須要在ZK7.0.3的ViewModel中下載該文件。html

思路

先從MongoDB獲取到OutputStream,以及把OutputStream轉化爲ZK的Filedownload可以使用的InputStream進行文件下載。java

實現

導入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流方式不少,主要三種:mongodb

  • 使用緩存流轉化
  • 使用管道流轉化
  • 使用循環緩存流轉化

緩存流:

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多線程

相關文章
相關標籤/搜索