Overview
En esta guía, aprenderá a almacenar y recuperar archivos grandes en MongoDB con GridFS. El sistema de almacenamiento GridFS divide los archivos en fragmentos al almacenarlos y los reensambla al recuperarlos. La implementación de GridFS en el controlador es una abstracción que gestiona las operaciones y la organización del almacenamiento de archivos.
Utilice GridFS si el tamaño de alguno de sus archivos supera el límite de tamaño de documento BSON de 16 MB. Para obtener información más detallada sobre si GridFS es adecuado para su caso de uso, consulte GridFS en el manual del servidor MongoDB.
Cómo funciona GridFS
GridFS organiza los archivos en un bucket, un grupo de colecciones de MongoDB que contiene fragmentos de archivos e información que los describe. El bucket contiene las siguientes colecciones:
chunks:Almacena los fragmentos de archivos binariosfiles:Almacena los metadatos del archivo
El controlador crea el bucket de GridFS, si aún no existe, la primera vez que se escriben datos en él. El bucket contiene las colecciones chunks y files, con el prefijo predeterminado fs, a menos que se especifique otro. Para garantizar una recuperación eficiente de los archivos y los metadatos relacionados, el controlador crea un índice en cada colección. El controlador se asegura de que estos índices existan antes de realizar operaciones de lectura y escritura en el bucket de GridFS.
Para obtener más información sobre los índices GridFS,consulte Índices GridFS en el manual del servidor MongoDB.
Al usar GridFS para almacenar archivos, el controlador los divide en fragmentos más pequeños, cada uno representado por un documento independiente en la colección chunks. También crea un documento en la colección files que contiene el ID, el nombre y otros metadatos del archivo.
El siguiente diagrama muestra cómo GridFS divide los archivos cuando se cargan en un depósito:

Al recuperar archivos, GridFS obtiene los metadatos de la colección files en el depósito especificado y utiliza la información para reconstruir el archivo a partir de los documentos de la colección chunks.
Crear un bucket de GridFS
Para empezar a usar GridFS para almacenar o recuperar archivos, cree una nueva instancia de la clase GridFSBucket y pase un objeto IMongoDatabase que represente su base de datos. Este método accede a un contenedor existente o crea uno nuevo si no existe.
El siguiente ejemplo crea una nueva instancia de la clase GridFSBucket para la base de datos db:
var client = new MongoClient("<connection string>"); var database = client.GetDatabase("db"); // Creates a GridFS bucket or references an existing one var bucket = new GridFSBucket(database);
Personaliza el cubo
Puede personalizar la configuración del bucket de GridFS pasando una instancia de la clase GridFSBucketOptions al constructor GridFSBucket(). La siguiente tabla describe las propiedades de la clase GridFSBucketOptions:
Campo | Descripción |
|---|---|
| El nombre del depósito que se usará como prefijo para las colecciones de archivos y fragmentos. El valor predeterminado es Tipo de dato: |
| El tamaño del fragmento en el que GridFS divide los archivos. El valor predeterminado es 255 KB. Tipo de dato: |
| La preocupación de lectura que se utiliza para las operaciones de depósito. El valor predeterminado es la preocupación de lectura de la base de datos. Tipo de datos: ReadConcern |
| La preferencia de lectura que se utilizará para las operaciones de bucket. El valor por defecto es la preferencia de lectura de la base de datos. Tipo de dato: ReadPreference |
| Preocupación de escritura que se utiliza para las operaciones de depósito. El valor predeterminado es la preocupación de escritura de la base de datos. Tipo de dato: WriteConcern |
El siguiente ejemplo crea un depósito llamado "myCustomBucket" pasando una instancia de la clase GridFSBucketOptions al constructor GridFSBucket():
var options = new GridFSBucketOptions { BucketName = "myCustomBucket" }; var customBucket = new GridFSBucket(database, options);
Cargar archivos
Puede cargar archivos a un depósito GridFS mediante los siguientes métodos:
OpenUploadStream()oOpenUploadStreamAsync(): abre un nuevo flujo de carga en el que puede escribir el contenido del archivoUploadFromStream()oUploadFromStreamAsync(): Sube el contenido de una secuencia existente a un archivo GridFS
Las siguientes secciones describen cómo utilizar estos métodos.
Escribir en un flujo de carga
Utilice el método OpenUploadStream() o OpenUploadStreamAsync() para crear un flujo de carga para un nombre de archivo determinado. Estos métodos aceptan los siguientes parámetros:
Parameter | Descripción |
|---|---|
| El nombre del archivo a cargar. Tipo de dato: |
| Opcional. Una instancia de la Tipo de dato: GridFSUploadOptions |
| Opcional. Un token que puedes usar para cancelar la operación. Tipo de dato: CancellationToken |
Este ejemplo de código demuestra cómo abrir un flujo de carga realizando los siguientes pasos:
Llama al método
OpenUploadStream()para abrir una secuencia GridFS escribible para un archivo llamado"my_file"Llama al método
Write()para escribir datos enmy_fileLlama al método
Close()para cerrar la secuencia que apunta amy_file
Seleccione el Synchronous o pestaña Asynchronous para ver el código correspondiente:
using (var uploader = bucket.OpenUploadStream("my_file")) { // ASCII for "HelloWorld" byte[] bytes = { 72, 101, 108, 108, 111, 87, 111, 114, 108, 100 }; uploader.Write(bytes, 0, bytes.Length); uploader.Close(); }
using (var uploader = await bucket.OpenUploadStreamAsync("my_file", options)) { // ASCII for "HelloWorld" byte[] bytes = { 72, 101, 108, 108, 111, 87, 111, 114, 108, 100 }; await uploader.WriteAsync(bytes, 0, bytes.Length); await uploader.CloseAsync(); }
Para personalizar la configuración del flujo de carga, pase una instancia de la clase GridFSUploadOptions al método OpenUploadStream() o OpenUploadStreamAsync(). La clase GridFSUploadOptions contiene las siguientes propiedades:
Propiedad | Descripción |
|---|---|
| Número de fragmentos que se cargarán en cada lote. El valor predeterminado es 16 MB dividido entre el valor de la propiedad Tipo de dato: |
| El tamaño de cada fragmento, excepto el último, que es más pequeño. El valor predeterminado es 255 KB. Tipo de dato: |
| Metadatos para almacenar con el archivo, incluidos los siguientes elementos:
El valor por defecto es Tipo de dato: BsonDocument |
El siguiente ejemplo realiza los mismos pasos que el anterior, pero también utiliza la opción ChunkSizeBytes para especificar el tamaño de cada fragmento. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente.
Subir una transmisión existente
Utilice el método UploadFromStream() o UploadFromStreamAsync() para cargar el contenido de una secuencia a un nuevo archivo GridFS. Estos métodos aceptan los siguientes parámetros:
Parameter | Descripción |
|---|---|
| El nombre del archivo a cargar. Tipo de dato: |
| La secuencia desde la que se leerá el contenido del archivo. Tipo de dato: Flujo |
| Opcional. Una instancia de la Tipo de dato: GridFSUploadOptions |
| Opcional. Un token que puedes usar para cancelar la operación. Tipo de dato: CancellationToken |
Este ejemplo de código demuestra cómo abrir un flujo de carga realizando los siguientes pasos:
Abre un archivo ubicado en
/path/to/input_filecomo una secuencia en modo de lectura binariaLlama al método
UploadFromStream()para escribir el contenido de la transmisión en un archivo GridFS llamado"new_file"
Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente.
using (var fileStream = new FileStream("/path/to/input_file", FileMode.Open, FileAccess.Read)) { bucket.UploadFromStream("new_file", fileStream); }
using (var fileStream = new FileStream("/path/to/input_file", FileMode.Open, FileAccess.Read)) { await bucket.UploadFromStreamAsync("new_file", fileStream); }
Descarga de archivos
Puede descargar archivos de un depósito GridFS mediante los siguientes métodos:
OpenDownloadStream()oOpenDownloadStreamAsync(): abre una nueva secuencia de descarga desde la que puede leer el contenido del archivoDownloadToStream()oDownloadToStreamAsync(): Escribe el contenido de un archivo GridFS en un flujo existente
Las siguientes secciones describen estos métodos con más detalle.
Leer desde un flujo de descarga
Utilice el método OpenDownloadStream() o OpenDownloadStreamAsync() para crear un flujo de descarga. Estos métodos aceptan los siguientes parámetros:
Parameter | Descripción |
|---|---|
| El valor Tipo de dato: BsonValue |
| Opcional. Una instancia de la Tipo de dato: GridFSDownloadOptions |
| Opcional. Un token que puedes usar para cancelar la operación. Tipo de dato: CancellationToken |
El siguiente ejemplo de código demuestra cómo abrir un flujo de descarga realizando los siguientes pasos:
Recupera el valor
_iddel archivo GridFS llamado"new_file"Llama al método
OpenDownloadStream()y pasa el valor_idpara abrir el archivo como una secuencia GridFS legibleCrea un vector
bufferpara almacenar el contenido del archivoLlama al método
Read()para leer el contenido del archivo desde el flujodownloaderal vector
Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente.
var filter = Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, "new_file"); var doc = bucket.Find(filter).FirstOrDefault(); if (doc != null) { using (var downloader = bucket.OpenDownloadStream(doc.Id)) { var buffer = new byte[downloader.Length]; downloader.Read(buffer, 0, buffer.Length); // Process the buffer as needed } }
var filter = Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, "new_file"); var cursor = await bucket.FindAsync(filter); var fileInfoList = await cursor.ToListAsync(); var doc = fileInfoList.FirstOrDefault(); if (doc != null) { using (var downloader = await bucket.OpenDownloadStreamAsync(doc.Id)) { var buffer = new byte[downloader.Length]; await downloader.ReadAsync(buffer, 0, buffer.Length); // Process the buffer as needed } }
Para personalizar la configuración del flujo de descarga, pase una instancia de la clase GridFSDownloadOptions al método OpenDownloadStream(). La clase GridFSDownloadOptions contiene la siguiente propiedad:
Propiedad | Descripción |
|---|---|
| Indica si el flujo admite la búsqueda, la consulta y la modificación de la posición actual. El valor predeterminado Tipo de dato: |
El siguiente ejemplo realiza los mismos pasos que el ejemplo anterior, pero también establece la opción Seekable en true para especificar que la secuencia se puede buscar.
Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente.
Descargar a una transmisión existente
Utilice el método DownloadToStream() o DownloadToStreamAsync() para descargar el contenido de un archivo GridFS a una secuencia existente. Estos métodos aceptan los siguientes parámetros:
Parameter | Descripción |
|---|---|
| El valor Tipo de dato: BsonValue |
| El flujo donde el controlador .NET/C# descarga el archivo GridFS. El valor de esta propiedad debe ser un objeto que implemente la clase Tipo de dato: Flujo |
| Opcional. Una instancia de la Tipo de dato: GridFSDownloadOptions |
| Opcional. Un token que puedes usar para cancelar la operación. Tipo de dato: CancellationToken |
El siguiente ejemplo de código demuestra cómo descargar a una transmisión existente realizando las siguientes acciones:
Abre un archivo ubicado en
/path/to/output_filecomo una secuencia en modo de escritura binariaRecupera el valor
_iddel archivo GridFS llamado"new_file"Llama al método
DownloadToStream()y pasa el valor_idpara descargar el contenido de"new_file"a una secuencia
Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente.
var filter = Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, "new_file"); var doc = bucket.Find(filter).FirstOrDefault(); if (doc != null) { using (var outputFile = new FileStream("/path/to/output_file", FileMode.Create, FileAccess.Write)) { bucket.DownloadToStream(doc.Id, outputFile); } }
var filter = Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, "new_file"); var cursor = await bucket.FindAsync(filter); var fileInfoList = await cursor.ToListAsync(); var doc = fileInfoList.FirstOrDefault(); if (doc != null) { using (var outputFile = new FileStream("/path/to/output_file", FileMode.Create, FileAccess.Write)) { await bucket.DownloadToStreamAsync(doc.Id, outputFile); } }
Buscar archivos
Para buscar archivos en un bucket de GridFS, llame al método Find() o FindAsync() en su instancia GridFSBucket. Estos métodos aceptan los siguientes parámetros:
Parameter | Descripción |
|---|---|
| Un filtro de consulta que especifica las entradas que deben coincidir en la colección Tipo de |
| La secuencia desde la que se leerá el contenido del archivo. Tipo de dato: Flujo |
| Opcional. Una instancia de la Tipo de dato: GridFSFindOptions |
| Opcional. Un token que puedes usar para cancelar la operación. Tipo de dato: CancellationToken |
El siguiente ejemplo de código muestra cómo recuperar e imprimir metadatos de archivos en un bucket de GridFS. El Find() método devuelve una IAsyncCursor<GridFSFileInfo> instancia desde la que se puede acceder a los resultados. Utiliza un foreach bucle para iterar sobre el cursor devuelto y mostrar el contenido de los archivos cargados en los ejemplos de carga de archivos.
Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente.
var filter = Builders<GridFSFileInfo>.Filter.Empty; var files = bucket.Find(filter); foreach (var file in files.ToEnumerable()) { Console.WriteLine(file.ToJson()); }
{ "_id" : { "$oid" : "..." }, "length" : 13, "chunkSize" : 261120, "uploadDate" : { "$date" : ... }, "filename" : "new_file" } { "_id" : { "$oid" : "..." }, "length" : 50, "chunkSize" : 1048576, "uploadDate" : { "$date" : ... }, "filename" : "my_file" }
var filter = Builders<GridFSFileInfo>.Filter.Empty; var files = await bucket.FindAsync(filter); await files.ForEachAsync(file => Console.Out.WriteLineAsync(file.ToJson()))
{ "_id" : { "$oid" : "..." }, "length" : 13, "chunkSize" : 261120, "uploadDate" : { "$date" : ... }, "filename" : "new_file" } { "_id" : { "$oid" : "..." }, "length" : 50, "chunkSize" : 1048576, "uploadDate" : { "$date" : ... }, "filename" : "my_file" }
Para personalizar la operación de búsqueda, pasa una instancia de la clase GridFSFindOptions al método Find() o FindAsync(). La clase GridFSFindOptions contiene las siguientes propiedades:
Propiedad | Descripción |
|---|---|
| El orden de clasificación de los resultados. Si no se especifica ningún orden de clasificación, el método devuelve los resultados en el orden en que se insertaron. Tipo de |
Eliminar archivos
Para eliminar archivos de un bucket de GridFS, llame al método Delete() o DeleteAsync() en su instancia GridFSBucket. Este método elimina la colección de metadatos de un archivo y sus fragmentos asociados del bucket.
Los métodos Delete y DeleteAsync() aceptan los siguientes parámetros:
Parameter | Descripción |
|---|---|
| El Tipo de dato: BsonValue |
| Opcional. Un token que puedes usar para cancelar la operación. Tipo de dato: CancellationToken |
El siguiente ejemplo de código muestra cómo eliminar un archivo llamado "my_file" pasando su valor _id a delete_file():
Utiliza la clase
Builderspara crear un filtro que coincida con el archivo llamado"my_file"Utiliza el método
Find()para encontrar el archivo llamado"my_file"Pasa el valor
_iddel archivo al métodoDelete()para eliminar el archivo
Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente.
var filter = Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, "new_file"); var doc = bucket.Find(filter).FirstOrDefault(); if (doc != null) { bucket.Delete(doc.Id); }
var filter = Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, "new_file"); var cursor = await bucket.FindAsync(filter); var fileInfoList = await cursor.ToListAsync(); var doc = fileInfoList.FirstOrDefault(); if (doc != null) { await bucket.DeleteAsync(doc.Id); }
Nota
Revisiones de archivos
Los métodos Delete() y DeleteAsync() solo permiten eliminar un archivo a la vez. Si desea eliminar cada revisión de archivo, o archivos con diferentes tiempos de carga que comparten el mismo nombre, recopile los valores _id de cada revisión. Luego, pase cada valor _id en llamadas separadas al método Delete() o DeleteAsync().
Documentación de la API
Para obtener más información sobre las clases utilizadas en esta página, consulte la siguiente documentación de API:
Para obtener más información sobre los métodos de la clase GridFSBucket utilizados en esta página, consulte la siguiente documentación de API: