GridFSDownloadStream无法读取所有数据

时间:2016-03-23 10:10:35

标签: java mongodb gridfs

我尝试从mongodb下载文件。上传文件的大小为2106个字节,chunkSize=2048个字节,因此GridFS将文件分为2个块​​。当我执行downloadStream.read(bytesToWriteTo)的代码时,只读取第一个块的数据,而不能读取第二个块的数据。我怎样才能读取所有数据?

public class OpenDownloadStreamDemo {

          public static void main(String[] args) {
            MongoClient mongoClient = new MongoClient("127.0.0.1", 27017);
            MongoDatabase mongoDatabase = mongoClient.getDatabase("demo");
            GridFSBucket gridFSBucket = GridFSBuckets[enter image description here][1].create(mongoDatabase);
            ObjectId fileId = new ObjectId("56f25a8b163b4598987b666b");
            GridFSDownloadStream downloadStream = gridFSBucket.openDownloadStream(fileId);
            int fileLength = (int) downloadStream.getGridFSFile().getLength();
            byte[] bytesToWriteTo = new byte[fileLength];
            downloadStream.read(bytesToWriteTo);
            downloadStream.close();
            System.out.println(new String(bytesToWriteTo, StandardCharsets.UTF_8));
        }
    }

The files Collection

The chunks Collection

3 个答案:

答案 0 :(得分:1)

我知道这是一个非常晚的回复,您可以尝试使用以下实现

public static void main(String[] args) {
        MongoClient mongoClient = new MongoClient("127.0.0.1", 27017);
        MongoDatabase mongoDatabase = mongoClient.getDatabase("demo");
        GridFSBucket gridFSBucket = GridFSBuckets.create(mongoDatabase);
        ObjectId fileId = new ObjectId("56f25a8b163b4598987b666b");
        GridFSDownloadStream downloadStream = gridFSBucket.openDownloadStream(fileId);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        int data = downloadStream.read();
        while (data >= 0) {
            outputStream.write((char) data);
            data = downloadStream.read();
        }
        byte[] bytesToWriteTo = outputStream.toByteArray();
        downloadStream.close();
        System.out.println(new String(bytesToWriteTo, StandardCharsets.UTF_8));
    }
}

答案 1 :(得分:0)

您可以直接使用输入流。打开的下载流足以获得所有块

GridFSDownloadStream downloadStream = mongo.getGridFSBucket().openDownloadStream(fileId);    
//int fileLength = (int) downloadStream.getGridFSFile().getLength();    
//byte[] bytesToWriteTo = new byte[(fileLength];    
//downloadStream.read(bytesToWriteTo);    
return downloadStream;   

答案 2 :(得分:0)

这让我难以忍受了一天,GridFS页面上的示例只调用了一次读取,但是为了下载所有的块,你需要重复调​​用它。每次调用都会返回从当前块读取的字节数,因此您必须将值相加以跟踪当前位置并将该值传递回read(...)以便将chuck复制到正确的位置在您的字节数组中的位置。这就是我实施它的方式。

public class OpenDownloadStreamDemo {

      public static void main(String[] args) {
        MongoClient mongoClient = new MongoClient("127.0.0.1", 27017);
        MongoDatabase mongoDatabase = mongoClient.getDatabase("demo");
        GridFSBucket gridFSBucket = GridFSBuckets[enter image description here][1].create(mongoDatabase);
        ObjectId fileId = new ObjectId("56f25a8b163b4598987b666b");
        GridFSDownloadStream downloadStream = gridFSBucket.openDownloadStream(fileId);
        int fileLength = (int) downloadStream.getGridFSFile().getLength();
        byte[] bytesToWriteTo = new byte[fileLength];
        int streamDownloadPosition = 0;
        while(streamDownloadPosition != -1) {
            streamDownloadPosition += downloadStream.read(bytesToWriteTo, streamDownloadPosition, fileLength);
        }
        downloadStream.close();
        System.out.println(new String(bytesToWriteTo, StandardCharsets.UTF_8));
    }
}