GridFS es una especificación para almacenar y recuperar archivos que exceden el límite de tamaño de documento BSON de 16 MB. En lugar de almacenar un gran archivo en un único documento, GridFS divide un archivo en partes, o fragmentos, y almacena cada uno de estos fragmentos como documentos independientes.
Cuando consultas un almacén GridFS para un archivo, el controlador vuelve a montar los fragmentos según sea necesario.
Los ejemplos de código de esta guía provienen de la Archivo GridFSTour.java en el repositorio de código fuente del controlador en GitHub.
Requisitos previos
Debes incluir las siguientes instrucciones de importación en tu programa para ejecutar los ejemplos de código de esta guía:
import com.mongodb.reactivestreams.client.MongoClients; import com.mongodb.reactivestreams.client.MongoClient; import com.mongodb.reactivestreams.client.MongoDatabase; import com.mongodb.client.gridfs.model.*; import com.mongodb.reactivestreams.client.gridfs.*; import org.bson.Document; import org.bson.types.ObjectId; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import static com.mongodb.client.model.Filters.eq; import static reactivestreams.helpers.PublisherHelpers.toPublisher;
Importante
Esta guía usa Subscriber implementaciones, que se describen en el Guíade implementación de suscriptores personalizados de muestra.
Conectarse a una implementación de MongoDB
Primero, conéctese a una implementación de MongoDB y declare y defina una instancia MongoDatabase.
El siguiente código se conecta a una implementación independiente de MongoDB que se ejecuta en localhost en el puerto 27017:
MongoClient mongoClient = MongoClients.create();
Para aprender más sobre cómo conectar implementaciones de MongoDB, consulta el tutorial Conectar a MongoDB.
Crear un bucket de GridFS
GridFS almacena archivos en dos colecciones:
chunks: almacena los fragmentos de archivosfiles: stores file metadata
Las dos colecciones están en un bucket común y los nombres de las colecciones llevan el prefijo del nombre del bucket.
El driver proporciona el método GridFSBuckets.create() para crear instancias de GridFSBucket:
MongoDatabase myDatabase = mongoClient.getDatabase("mydb"); // Create a gridFSBucket using the default bucket name "fs" GridFSBucket gridFSBucket = GridFSBuckets.create(myDatabase);
Nota
GridFS crea automáticamente índices en las colecciones files y chunks cuando cargas datos en el bucket de GridFS.
Puede pasar un nombre de depósito al método GridFSBuckets.create():
// Create a gridFSBucket with a custom bucket name "files" GridFSBucket gridFSFilesBucket = GridFSBuckets.create(myDatabase, "files");
Tip
Configuración de Tiempo de Espera
Puede usar la configuración de tiempo de espera de operaciones del lado del cliente (CSOT) para limitar la cantidad de tiempo en que el servidor puede finalizar las operaciones de GridFS. Para aprender más sobre el uso de esta configuración con GridFS, consulta la sección GridFS de la guía Tiempo límite de ejecución del servidor.
Subir a GridFS
El método GridFSBucket.uploadFromPublisher() lee el contenido de Publisher<ByteBuffer> y lo guarda en la instancia de GridFSBucket.
Puede utilizar el tipo GridFSUploadOptions para configurar el tamaño del fragmento o incluir metadatos adicionales.
El siguiente ejemplo carga el contenido de un/una Publisher<ByteBuffer> en GridFSBucket:
// Get the input publisher Publisher<ByteBuffer> publisherToUploadFrom = toPublisher( ByteBuffer .wrap("MongoDB Tutorial..".getBytes(StandardCharsets.UTF_8)) ); // Create some custom options GridFSUploadOptions options = new GridFSUploadOptions() .chunkSizeBytes(1024) .metadata(new Document("type", "presentation")); ObservableSubscriber<ObjectId> uploadSubscriber = new OperationSubscriber<>(); gridFSBucket.uploadFromPublisher("mongodb-tutorial", publisherToUploadFrom, options).subscribe(uploadSubscriber); ObjectId fileId = uploadSubscriber.get().get(0);
Encontrar archivos almacenados en GridFS
Para encontrar los archivos almacenados en GridFSBucket, utiliza el método find().
El siguiente ejemplo imprime el nombre de archivo de cada archivo almacenado:
ConsumerSubscriber<GridFSFile> filesSubscriber = new ConsumerSubscriber<>(gridFSFile -> System.out.println(" - " + gridFSFile.getFilename())); gridFSBucket.find().subscribe(filesSubscriber); filesSubscriber.await();
También puede proporcionar un filtro personalizado para limitar los resultados devueltos. El siguiente ejemplo imprime los nombres de todos los archivos cuyo valor contentType es image/png en el documento de metadatos definido por el usuario:
filesSubscriber = new ConsumerSubscriber<>(gridFSFile -> System.out.println("Found: " + gridFSFile.getFilename())); gridFSBucket.find(eq("metadata.contentType", "image/png")).subscribe(filesSubscriber); filesSubscriber.await();
Descargar desde GridFS
El método downloadToPublisher() retorna un Publisher<ByteBuffer> que lee el contenido desde MongoDB.
Para descargar un archivo por su _id de archivo, pasa el _id al método. El siguiente ejemplo descarga un archivo por su archivo _id:
ObjectId fileId; ObservableSubscriber<ByteBuffer> downloadSubscriber = new OperationSubscriber<>(); gridFSBucket.downloadToPublisher(fileId).subscribe(downloadSubscriber);
Si no conoces el _id del archivo pero conoces el nombre del archivo, puedes pasar el nombre del archivo al método downloadToPublisher(). Por defecto, se descargará la última versión del archivo. Utilice la clase GridFSDownloadOptions para configurar qué versión descargar.
El siguiente ejemplo descarga la versión original del archivo llamado mongodb-tutorial:
GridFSDownloadOptions downloadOptions = new GridFSDownloadOptions().revision(0); downloadSubscriber = new OperationSubscriber<>(); gridFSBucket.downloadToPublisher("mongodb-tutorial", downloadOptions).subscribe(downloadSubscriber);
Renombrar archivos
Si necesitas cambiar el nombre de un archivo, entonces utiliza el método rename().
El siguiente ejemplo renombra un archivo a mongodbTutorial:
ObjectId fileId; //ObjectId of a file uploaded to GridFS gridFSBucket.rename(fileId, "mongodbTutorial").subscribe(new ObservableSubscriber<Void>());
Nota
El método rename() requiere un ObjectId en lugar de un filename para garantizar que se cambie el nombre del archivo correcto.
Para renombrar varias revisiones del mismo nombre de archivo, primero recupere la lista completa de archivos. Después, para cada archivo que deba renombrarse, ejecute rename() con el correspondiente _id.
Borrar archivos
Para borrar un archivo del GridFSBucket, usa el método delete().
El siguiente ejemplo elimina un archivo de GridFSBucket:
ObjectId fileId; //ObjectId of a file uploaded to GridFS gridFSBucket.delete(fileId).subscribe(new ObservableSubscriber<Void>());