The MongoDB Synchronous Driver for Java providing blocking I/O patterns for database operations
—
Large file storage and retrieval system with streaming upload/download capabilities, file metadata management, and efficient handling of files exceeding BSON document size limits.
Factory class for creating GridFS bucket instances with default or custom configurations.
/**
* Factory for creating GridFS buckets
*/
public final class GridFSBuckets {
/**
* Creates a GridFS bucket with default name 'fs'
* @param database the database to create the bucket in
* @return GridFSBucket instance with default configuration
*/
public static GridFSBucket create(MongoDatabase database);
/**
* Creates a GridFS bucket with custom name
* @param database the database to create the bucket in
* @param bucketName the name of the GridFS bucket
* @return GridFSBucket instance with specified bucket name
*/
public static GridFSBucket create(MongoDatabase database, String bucketName);
}Usage Examples:
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import com.mongodb.client.MongoDatabase;
// Create default GridFS bucket (uses 'fs' collections)
MongoDatabase database = client.getDatabase("myapp");
GridFSBucket gridFSBucket = GridFSBuckets.create(database);
// Create custom named bucket (uses 'photos.files' and 'photos.chunks')
GridFSBucket photoBucket = GridFSBuckets.create(database, "photos");
GridFSBucket documentBucket = GridFSBuckets.create(database, "documents");Primary interface for GridFS operations including file upload, download, and management.
/**
* Interface for GridFS bucket operations
*/
public interface GridFSBucket {
/**
* Gets the name of this GridFS bucket
* @return the bucket name
*/
String getBucketName();
/**
* Gets the default chunk size in bytes
* @return chunk size in bytes
*/
int getChunkSizeBytes();
/**
* Opens an upload stream for a new file
* @param filename the name of the file
* @return GridFSUploadStream for writing file data
*/
GridFSUploadStream openUploadStream(String filename);
/**
* Opens an upload stream with specific file ID
* @param id the file ID as BsonValue
* @param filename the name of the file
* @return GridFSUploadStream for writing file data
*/
GridFSUploadStream openUploadStream(BsonValue id, String filename);
/**
* Opens an upload stream with upload options
* @param filename the name of the file
* @param options upload configuration options
* @return GridFSUploadStream for writing file data
*/
GridFSUploadStream openUploadStream(String filename, GridFSUploadOptions options);
/**
* Uploads a file from an InputStream
* @param filename the name of the file
* @param source the InputStream to read from
* @return ObjectId of the uploaded file
*/
ObjectId uploadFromStream(String filename, InputStream source);
/**
* Uploads a file with specific ID from an InputStream
* @param id the file ID as BsonValue
* @param filename the name of the file
* @param source the InputStream to read from
*/
void uploadFromStream(BsonValue id, String filename, InputStream source);
/**
* Uploads a file with options from an InputStream
* @param filename the name of the file
* @param source the InputStream to read from
* @param options upload configuration options
* @return ObjectId of the uploaded file
*/
ObjectId uploadFromStream(String filename, InputStream source, GridFSUploadOptions options);
/**
* Opens a download stream by file ID
* @param id the file ID as ObjectId
* @return GridFSDownloadStream for reading file data
*/
GridFSDownloadStream openDownloadStream(ObjectId id);
/**
* Opens a download stream by file ID as BsonValue
* @param id the file ID as BsonValue
* @return GridFSDownloadStream for reading file data
*/
GridFSDownloadStream openDownloadStream(BsonValue id);
/**
* Opens a download stream by filename (latest version)
* @param filename the name of the file
* @return GridFSDownloadStream for reading file data
*/
GridFSDownloadStream openDownloadStream(String filename);
/**
* Opens a download stream by filename with options
* @param filename the name of the file
* @param options download configuration options
* @return GridFSDownloadStream for reading file data
*/
GridFSDownloadStream openDownloadStream(String filename, GridFSDownloadOptions options);
/**
* Downloads a file to an OutputStream by ID
* @param id the file ID as ObjectId
* @param destination the OutputStream to write to
*/
void downloadToStream(ObjectId id, OutputStream destination);
/**
* Downloads a file to an OutputStream by ID as BsonValue
* @param id the file ID as BsonValue
* @param destination the OutputStream to write to
*/
void downloadToStream(BsonValue id, OutputStream destination);
/**
* Downloads a file to an OutputStream by filename
* @param filename the name of the file
* @param destination the OutputStream to write to
*/
void downloadToStream(String filename, OutputStream destination);
/**
* Deletes a file by ID
* @param id the file ID as ObjectId
*/
void delete(ObjectId id);
/**
* Deletes a file by ID as BsonValue
* @param id the file ID as BsonValue
*/
void delete(BsonValue id);
/**
* Renames a file by ID
* @param id the file ID as ObjectId
* @param newFilename the new filename
*/
void rename(ObjectId id, String newFilename);
/**
* Renames a file by ID as BsonValue
* @param id the file ID as BsonValue
* @param newFilename the new filename
*/
void rename(BsonValue id, String newFilename);
/**
* Finds files in the bucket
* @return GridFSFindIterable for querying files
*/
GridFSFindIterable find();
/**
* Finds files matching a filter
* @param filter the query filter as Bson
* @return GridFSFindIterable for querying files
*/
GridFSFindIterable find(Bson filter);
/**
* Drops the entire GridFS bucket (files and chunks collections)
*/
void drop();
}Usage Examples:
import com.mongodb.client.gridfs.model.GridFSUploadOptions;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ByteArrayInputStream;
// Upload file from InputStream
try (FileInputStream fileInput = new FileInputStream("large-document.pdf")) {
ObjectId fileId = gridFSBucket.uploadFromStream("large-document.pdf", fileInput);
System.out.println("File uploaded with ID: " + fileId);
}
// Upload with metadata and custom chunk size
Document metadata = new Document("contentType", "application/pdf")
.append("department", "legal")
.append("confidential", true);
GridFSUploadOptions uploadOptions = new GridFSUploadOptions()
.chunkSizeBytes(1024 * 1024) // 1MB chunks
.metadata(metadata);
try (FileInputStream fileInput = new FileInputStream("contract.pdf")) {
ObjectId fileId = gridFSBucket.uploadFromStream("contract.pdf", fileInput, uploadOptions);
System.out.println("Contract uploaded with ID: " + fileId);
}
// Download file to OutputStream
try (FileOutputStream fileOutput = new FileOutputStream("downloaded-contract.pdf")) {
gridFSBucket.downloadToStream(fileId, fileOutput);
System.out.println("File downloaded successfully");
}
// Stream-based upload for large files
GridFSUploadStream uploadStream = gridFSBucket.openUploadStream("streaming-upload.dat");
try {
// Write data in chunks
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = sourceInputStream.read(buffer)) != -1) {
uploadStream.write(buffer, 0, bytesRead);
}
} finally {
uploadStream.close();
}
ObjectId streamFileId = uploadStream.getObjectId();OutputStream implementation for streaming file uploads to GridFS.
/**
* OutputStream for uploading files to GridFS
*/
public abstract class GridFSUploadStream extends OutputStream {
/**
* Gets the ObjectId of the file being uploaded
* @return ObjectId of the file
*/
public abstract ObjectId getObjectId();
/**
* Gets the BsonValue ID of the file being uploaded
* @return BsonValue ID of the file
*/
public abstract BsonValue getId();
/**
* Writes a byte to the stream
* @param b the byte to write
*/
@Override
public abstract void write(int b) throws IOException;
/**
* Writes a byte array to the stream
* @param b the byte array to write
* @param off the start offset
* @param len the number of bytes to write
*/
@Override
public abstract void write(byte[] b, int off, int len) throws IOException;
/**
* Flushes the stream
*/
@Override
public abstract void flush() throws IOException;
/**
* Closes the stream and completes the upload
*/
@Override
public abstract void close() throws IOException;
}Usage Examples:
// Progressive upload with progress tracking
GridFSUploadStream uploadStream = gridFSBucket.openUploadStream("progress-upload.bin");
try {
long totalBytes = sourceFile.length();
long uploadedBytes = 0;
byte[] buffer = new byte[64 * 1024]; // 64KB buffer
int bytesRead;
while ((bytesRead = sourceInputStream.read(buffer)) != -1) {
uploadStream.write(buffer, 0, bytesRead);
uploadedBytes += bytesRead;
// Report progress
double progress = (double) uploadedBytes / totalBytes * 100;
System.out.printf("Upload progress: %.1f%%\n", progress);
}
} finally {
uploadStream.close();
}
System.out.println("Upload completed. File ID: " + uploadStream.getObjectId());InputStream implementation for streaming file downloads from GridFS.
/**
* InputStream for downloading files from GridFS
*/
public abstract class GridFSDownloadStream extends InputStream {
/**
* Gets the GridFS file information
* @return GridFSFile containing file metadata
*/
public abstract GridFSFile getGridFSFile();
/**
* Reads a byte from the stream
* @return the byte read, or -1 if end of stream
*/
@Override
public abstract int read() throws IOException;
/**
* Reads bytes into a buffer
* @param b the buffer to read into
* @param off the start offset
* @param len the maximum number of bytes to read
* @return number of bytes read, or -1 if end of stream
*/
@Override
public abstract int read(byte[] b, int off, int len) throws IOException;
/**
* Skips bytes in the stream
* @param n the number of bytes to skip
* @return actual number of bytes skipped
*/
@Override
public abstract long skip(long n) throws IOException;
/**
* Returns available bytes to read
* @return number of available bytes
*/
@Override
public abstract int available() throws IOException;
/**
* Closes the stream
*/
@Override
public abstract void close() throws IOException;
}Usage Examples:
// Stream download with file information
try (GridFSDownloadStream downloadStream = gridFSBucket.openDownloadStream(fileId)) {
GridFSFile fileInfo = downloadStream.getGridFSFile();
System.out.println("Filename: " + fileInfo.getFilename());
System.out.println("File size: " + fileInfo.getLength() + " bytes");
System.out.println("Upload date: " + fileInfo.getUploadDate());
System.out.println("Content type: " + fileInfo.getMetadata().getString("contentType"));
// Read file in chunks
byte[] buffer = new byte[8192];
int bytesRead;
long totalRead = 0;
while ((bytesRead = downloadStream.read(buffer)) != -1) {
// Process chunk
processFileChunk(buffer, bytesRead);
totalRead += bytesRead;
// Progress reporting
double progress = (double) totalRead / fileInfo.getLength() * 100;
System.out.printf("Download progress: %.1f%%\n", progress);
}
}Query interface for finding and filtering GridFS files.
/**
* Interface for querying GridFS files
*/
public interface GridFSFindIterable extends MongoIterable<GridFSFile> {
/**
* Sets the query filter to limit results
* @param filter the query filter as Bson
* @return GridFSFindIterable with applied filter
*/
GridFSFindIterable filter(Bson filter);
/**
* Sets the maximum number of files to return
* @param limit the maximum number of files
* @return GridFSFindIterable with applied limit
*/
GridFSFindIterable limit(int limit);
/**
* Sets the number of files to skip
* @param skip the number of files to skip
* @return GridFSFindIterable with applied skip
*/
GridFSFindIterable skip(int skip);
/**
* Sets the sort criteria for results
* @param sort the sort specification as Bson
* @return GridFSFindIterable with applied sort
*/
GridFSFindIterable sort(Bson sort);
/**
* Sets whether to timeout the cursor
* @param noCursorTimeout true to disable cursor timeout
* @return GridFSFindIterable with cursor timeout setting
*/
GridFSFindIterable noCursorTimeout(boolean noCursorTimeout);
/**
* Sets the maximum execution time
* @param maxTime the maximum time
* @param timeUnit the time unit
* @return GridFSFindIterable with time limit
*/
GridFSFindIterable maxTime(long maxTime, TimeUnit timeUnit);
/**
* Sets the batch size for cursor operations
* @param batchSize the batch size
* @return GridFSFindIterable with specified batch size
*/
GridFSFindIterable batchSize(int batchSize);
/**
* Sets collation for string comparisons
* @param collation the collation specification
* @return GridFSFindIterable with applied collation
*/
GridFSFindIterable collation(Collation collation);
}Usage Examples:
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Sorts;
// Find all PDF files
GridFSFindIterable pdfFiles = gridFSBucket.find()
.filter(Filters.eq("metadata.contentType", "application/pdf"))
.sort(Sorts.descending("uploadDate"));
for (GridFSFile file : pdfFiles) {
System.out.println("PDF File: " + file.getFilename() +
" (Size: " + file.getLength() + " bytes)");
}
// Find large files uploaded recently
Date oneWeekAgo = Date.from(Instant.now().minus(7, ChronoUnit.DAYS));
GridFSFindIterable recentLargeFiles = gridFSBucket.find()
.filter(Filters.and(
Filters.gte("uploadDate", oneWeekAgo),
Filters.gte("length", 10 * 1024 * 1024) // 10MB+
))
.sort(Sorts.descending("length"))
.limit(10);
// Find files by custom metadata
GridFSFindIterable departmentFiles = gridFSBucket.find()
.filter(Filters.and(
Filters.eq("metadata.department", "marketing"),
Filters.eq("metadata.confidential", false)
))
.sort(Sorts.ascending("filename"));
// File cleanup - find old temporary files
Date thirtyDaysAgo = Date.from(Instant.now().minus(30, ChronoUnit.DAYS));
GridFSFindIterable tempFiles = gridFSBucket.find()
.filter(Filters.and(
Filters.regex("filename", "^temp_"),
Filters.lt("uploadDate", thirtyDaysAgo)
));
for (GridFSFile tempFile : tempFiles) {
System.out.println("Deleting old temp file: " + tempFile.getFilename());
gridFSBucket.delete(tempFile.getObjectId());
}GridFS bucket configuration and performance optimization techniques.
/**
* Configuration methods for GridFS buckets
*/
// Create bucket with custom codec registry
CodecRegistry codecRegistry = CodecRegistries.fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build())
);
GridFSBucket configuredBucket = gridFSBucket
.withCodecRegistry(codecRegistry)
.withReadPreference(ReadPreference.secondaryPreferred())
.withWriteConcern(WriteConcern.MAJORITY)
.withReadConcern(ReadConcern.MAJORITY);
// Optimize chunk size for different file types
GridFSUploadOptions smallFiles = new GridFSUploadOptions()
.chunkSizeBytes(64 * 1024); // 64KB for small files
GridFSUploadOptions largeFiles = new GridFSUploadOptions()
.chunkSizeBytes(2 * 1024 * 1024); // 2MB for large files
// Index optimization for file queries
MongoCollection<Document> filesCollection = database.getCollection(bucketName + ".files");
// Index for filename queries
filesCollection.createIndex(Indexes.ascending("filename"));
// Index for metadata queries
filesCollection.createIndex(Indexes.ascending("metadata.contentType"));
filesCollection.createIndex(Indexes.ascending("metadata.department"));
// Compound index for common queries
filesCollection.createIndex(Indexes.compound(
Indexes.ascending("metadata.department"),
Indexes.descending("uploadDate")
));Install with Tessl CLI
npx tessl i tessl/maven-org-mongodb--mongodb-driver-sync