Reputation: 1
I try to download file from mongodb . the size of uploaded file is 2106
bytes,and chunkSize=2048
bytes, so GridFS divides the file into 2 chunks. when I excute the codes of downloadStream.read(bytesToWriteTo)
, only read data of the first chunk, and can not read the data of second chunk. How can I read all of the data?
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));
}
}
Upvotes: 0
Views: 2328
Reputation: 1
This had me stumped for a day, the example on the GridFS page only calls read once, but in order to download all of the chunks you need to call it repeatedly. Each call returns you the number of bytes its read from the current chunk so you have to sum the values up to keep track of the current position and pass that value back into read(...) in order to copy the chuck into the correct position in your byte array. This was how I implemented it.
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));
}
}
Upvotes: 0
Reputation: 11
You can directly use the inputstream. The open download stream is enough to get all the chunks
GridFSDownloadStream downloadStream = mongo.getGridFSBucket().openDownloadStream(fileId);
//int fileLength = (int) downloadStream.getGridFSFile().getLength();
//byte[] bytesToWriteTo = new byte[(fileLength];
//downloadStream.read(bytesToWriteTo);
return downloadStream;
Upvotes: 0
Reputation: 11
I know it is a very late reply, you can try using following implementation
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));
}
}
Upvotes: 1