Docs Menu
Docs Home
/ /

Almacene archivos grandes

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.

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 binarios

  • files: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:

Un diagrama que muestra cómo GridFS sube un archivo a un bucket

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.

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);

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

BucketName

El nombre del depósito que se usará como prefijo para las colecciones de archivos y fragmentos. El valor predeterminado es "fs".

Tipo de dato: string

ChunkSizeBytes

El tamaño del fragmento en el que GridFS divide los archivos. El valor predeterminado es 255 KB.

Tipo de dato: integer

ReadConcern

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

ReadPreference

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

WriteConcern

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);

Puede cargar archivos a un depósito GridFS mediante los siguientes métodos:

  • OpenUploadStream() o OpenUploadStreamAsync(): abre un nuevo flujo de carga en el que puede escribir el contenido del archivo

  • UploadFromStream() o UploadFromStreamAsync(): Sube el contenido de una secuencia existente a un archivo GridFS

Las siguientes secciones describen cómo utilizar estos métodos.

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

filename

El nombre del archivo a cargar.

Tipo de dato: string

options

Opcional. Una instancia de la GridFSUploadOptions clase que especifica la configuración del flujo de carga. El valor predeterminado null es.

Tipo de dato: GridFSUploadOptions

cancellationToken

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 en my_file

  • Llama al método Close() para cerrar la secuencia que apunta a my_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

BatchSize

Número de fragmentos que se cargarán en cada lote. El valor predeterminado es 16 MB dividido entre el valor de la propiedad ChunkSizeBytes.

Tipo de dato: int?

ChunkSizeBytes

El tamaño de cada fragmento, excepto el último, que es más pequeño. El valor predeterminado es 255 KB.

Tipo de dato: int?

Metadata

Metadatos para almacenar con el archivo, incluidos los siguientes elementos:

  • El _id del archivo

  • El nombre del archivo

  • La longitud y el tamaño del archivo

  • La fecha y hora de carga

  • Un documento metadata en el que puedes almacenar otra información

El valor por defecto es null.

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.

var options = new GridFSUploadOptions
{
ChunkSizeBytes = 1048576 // 1 MB
};
using (var uploader = bucket.OpenUploadStream("my_file", options))
{
// ASCII for "HelloWorld"
byte[] bytes = { 72, 101, 108, 108, 111, 87, 111, 114, 108, 100 };
uploader.Write(bytes, 0, bytes.Length);
uploader.Close();
}
var options = new GridFSUploadOptions
{
ChunkSizeBytes = 1048576 // 1 MB
};
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();
}

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

filename

El nombre del archivo a cargar.

Tipo de dato: string

source

La secuencia desde la que se leerá el contenido del archivo.

Tipo de dato: Flujo

options

Opcional. Una instancia de la GridFSUploadOptions clase que especifica la configuración del flujo de carga. El valor predeterminado null es.

Tipo de dato: GridFSUploadOptions

cancellationToken

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_file como una secuencia en modo de lectura binaria

  • Llama 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);
}

Puede descargar archivos de un depósito GridFS mediante los siguientes métodos:

  • OpenDownloadStream() o OpenDownloadStreamAsync(): abre una nueva secuencia de descarga desde la que puede leer el contenido del archivo

  • DownloadToStream() o DownloadToStreamAsync(): Escribe el contenido de un archivo GridFS en un flujo existente

Las siguientes secciones describen estos métodos con más detalle.

Utilice el método OpenDownloadStream() o OpenDownloadStreamAsync() para crear un flujo de descarga. Estos métodos aceptan los siguientes parámetros:

Parameter
Descripción

id

El valor _id del archivo a descargar.

Tipo de dato: BsonValue

options

Opcional. Una instancia de la GridFSDownloadOptions clase que especifica la configuración del flujo de descarga. El valor predeterminado null es.

Tipo de dato: GridFSDownloadOptions

cancellationToken

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 _id del archivo GridFS llamado "new_file"

  • Llama al método OpenDownloadStream() y pasa el valor _id para abrir el archivo como una secuencia GridFS legible

  • Crea un vector buffer para almacenar el contenido del archivo

  • Llama al método Read() para leer el contenido del archivo desde el flujo downloader al 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

Seekable

Indica si el flujo admite la búsqueda, la consulta y la modificación de la posición actual. El valor predeterminado false es.

Tipo de dato: bool?

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.

var filter = Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, "new_file");
var doc = bucket.Find(filter).FirstOrDefault();
if (doc != null)
{
var options = new GridFSDownloadOptions
{
Seekable = true
};
using (var downloader = bucket.OpenDownloadStream(id, options))
{
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)
{
var options = new GridFSDownloadOptions
{
Seekable = true
};
using (var downloader = await bucket.OpenDownloadStreamAsync(doc.Id, options))
{
var buffer = new byte[downloader.Length];
await downloader.ReadAsync(buffer, 0, buffer.Length);
// Process the buffer as needed
}
}

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

id

El valor _id del archivo a descargar.

Tipo de dato: BsonValue

destination

El flujo donde el controlador .NET/C# descarga el archivo GridFS. El valor de esta propiedad debe ser un objeto que implemente la clase Stream.

Tipo de dato: Flujo

options

Opcional. Una instancia de la GridFSDownloadOptions clase que especifica la configuración del flujo de descarga. El valor predeterminado null es.

Tipo de dato: GridFSDownloadOptions

cancellationToken

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_file como una secuencia en modo de escritura binaria

  • Recupera el valor _id del archivo GridFS llamado "new_file"

  • Llama al método DownloadToStream() y pasa el valor _id para 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);
}
}

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

filter

Un filtro de consulta que especifica las entradas que deben coincidir en la colección files.

Tipo deFilterDefinition<GridFSFileInfo> dato:. Para obtener más información, consulte la documentación de la API del método Find().

source

La secuencia desde la que se leerá el contenido del archivo.

Tipo de dato: Flujo

options

Opcional. Una instancia de la GridFSFindOptions clase que especifica la configuración para la operación de búsqueda. El valor predeterminado null es.

Tipo de dato: GridFSFindOptions

cancellationToken

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

Sort

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 deSortDefinition<GridFSFileInfo> dato:. Para obtener más información, consulte la documentación de la API de la propiedad Sort.

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

id

El _id del archivo a eliminar.

Tipo de dato: BsonValue

cancellationToken

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 Builders para 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 _id del archivo al método Delete() 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. Para 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().

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:

Volver

Transacciones

En esta página