Overview
En esta guía, puedes aprender cómo almacenar y recuperar archivos grandes en MongoDB utilizando GridFS. GridFS es una especificación implementada por el driver C que describe cómo dividir los archivos en fragmentos al almacenarlos y volver a armarlos al recuperarlos. La implementación de GridFS del driver es una abstracción que gestiona las operaciones y la organización del almacenamiento de archivos.
Utiliza GridFS si el tamaño de los archivos supera el límite del tamaño del documento BSON de 16MB. Para obtener información más detallada sobre si GridFS es adecuado para tu caso de uso, consulta GridFS en el manual del MongoDB Server.
Cómo funciona GridFS
GridFS organiza los archivos en un bucket, un grupo de colecciones de MongoDB que contienen los fragmentos de archivos e información que los describe. El bucket contiene las siguientes colecciones, nombradas según la convención definida en la especificación GridFS:
La
chunksla colección almacena los fragmentos de archivos binarios.La colección
filesalmacena los metadatos de los archivos.
El driver crea el bucket de GridFS, si no existe, cuando ejecutas la primera operación de guardar. El bucket contiene las colecciones anteriores con el prefijo del nombre de bucket por defecto fs, a menos que indiques un nombre diferente. Para asegurar la recuperación eficiente de los archivos y metadatos relacionados, el driver también crea un índice en cada colección si no existen y cuando el bucket está vacío.
Para obtener más información sobre los índices de GridFS, consulta Índices de GridFS en el manual del servidor MongoDB.
Al usar GridFS para almacenar archivos, el driver divide los archivos 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 un ID de archivo, el nombre del archivo y otros metadatos del archivo. Puedes cargar el archivo pasando un stream al controlador C para su consumo o creando un nuevo stream y escribiendo directamente en él.
El siguiente diagrama muestra cómo GridFS divide los archivos cuando se cargan en un bucket.

Al recuperar archivos de GridFS, se obtiene los metadatos desde la colección files en el bucket especificado y se utiliza la información para reconstruir el archivo a partir de documentos en la colección chunks. Puedes leer el archivo escribiendo su contenido en una secuencia existente o creando una nueva secuencia que apunte al archivo.
Crear un bucket de GridFS
Para usar GridFS, primero llama a la función mongoc_gridfs_bucket_new(). Esta función crea una nueva estructura mongoc_gridfs_bucket_t o accede a una existente mongoc_gridfs_bucket_t y acepta los siguientes parámetros:
Base de datos: Especifica la base de datos en la que se va a crear el bucket
Documento de opciones: especifica las opciones para personalizar el bucket, o
NULLPreferencia de lectura: especifica la preferencia de lectura que se debe utilizar en las operaciones de lectura, o
NULLpara heredar la preferencia de lectura de la base de datosUbicación del error: Especifica una ubicación para un valor de error o
NULL
El siguiente ejemplo llama a la función mongoc_gridfs_bucket_new() y pasa la base de datos db como parámetro:
mongoc_database_t *db = mongoc_client_get_database(client, "db"); bson_error_t error; mongoc_gridfs_bucket_t *bucket = mongoc_gridfs_bucket_new(db, NULL, NULL, &error); if (!bucket) { fprintf(stderr, "Failed to create bucket: %s\n", error.message); }
Personaliza la cubeta
Puedes personalizar la configuración del bucket GridFS pasando un documento BSON que especifique los valores de opción a la función mongoc_gridfs_bucket_new(). La siguiente tabla describe las opciones que puedes configurar en el documento:
Opción | Descripción |
|---|---|
| Specifies the bucket name to use as a prefix for the files and chunks collections.
The default value is "fs".Type: string |
| Specifies the chunk size that GridFS splits files into. The default value is 255 kB. Type: int32 |
| Specifies the read concern to use for bucket operations. The default value is the
database's read concern. Type: mongoc_read_concern_t |
| Specifies the write concern to use for bucket operations. The default value is the
database's write concern. Type: mongoc_write_concern_t |
El siguiente ejemplo crea un contenedor llamado "myCustomBucket", pasando un documento de opciones a mongoc_gridfs_bucket_new() que establece la opción bucketName:
mongoc_database_t *db = mongoc_client_get_database(client, "db"); bson_t opts = BSON_INITIALIZER; BSON_APPEND_UTF8(&opts, "bucketName", "myCustomBucket"); bson_error_t error; if (!mongoc_gridfs_bucket_new(db, &opts, NULL, &error)) { fprintf(stderr, "Failed to create bucket: %s\n", error.message); }
Cargar archivos
Puede cargar archivos en un bucket GridFS utilizando las siguientes funciones:
mongoc_gridfs_bucket_open_upload_stream(): Abre un nuevo flujo de carga al que se pueden guardar los contenidos del archivomongoc_gridfs_bucket_upload_from_stream(): Sube el contenido de una secuencia existente a un archivo GridFS
Guardar en un flujo de carga
Utilice la función mongoc_gridfs_bucket_open_upload_stream() para crear un flujo de carga para un nombre de archivo determinado. La función mongoc_gridfs_bucket_open_upload_stream() permite especificar información de configuración en un documento de opciones, que se puede pasar como parámetro.
Este ejemplo utiliza una transmisión de carga para realizar las siguientes acciones:
Abre un flujo escribible para un nuevo archivo GridFS llamado
"my_file"Llama a la función
mongoc_stream_write()para escribir datos en"my_file", a la que apunta el flujoLlama a las funciones
mongoc_stream_close()ymongoc_stream_destroy()para cerrar y destruir el flujo que apunta a"my_file"
bson_error_t error; mongoc_stream_t *upload_stream = mongoc_gridfs_bucket_open_upload_stream(bucket, "my_file", NULL, NULL, &error); if (upload_stream == NULL) { fprintf(stderr, "Failed to create upload stream: %s\n", error.message); } else { const char *data = "Data to store"; mongoc_stream_write(upload_stream, data, strlen(data), -1); } mongoc_stream_close(upload_stream); mongoc_stream_destroy(upload_stream);
Subir un flujo existente
Utiliza la función mongoc_gridfs_bucket_upload_from_stream() para subir el contenido de un flujo a un nuevo archivo GridFS. La función mongoc_gridfs_bucket_upload_from_stream() te permite especificar la información de configuración en un documento de opciones, que puedes pasar como parámetro.
Este ejemplo realiza las siguientes acciones:
Llama a la función
mongoc_stream_file_new_for_path()para abrir un archivo ubicado en/path/to/input_filecomo un stream en modo solo lectura (O_RDONLY)Llama a la función
mongoc_gridfs_bucket_upload_from_stream()para cargar el contenido del flujo a un archivo GridFS denominado"new_file"Llama a las funciones
mongoc_stream_close()ymongoc_stream_destroy()para cerrar y destruir el flujo
mongoc_stream_t *file_stream = mongoc_stream_file_new_for_path("/path/to/input_file", O_RDONLY, 0); bson_error_t error; if (!mongoc_gridfs_bucket_upload_from_stream(bucket, "new_file", file_stream, NULL, NULL, &error)) { fprintf(stderr, "Failed to upload file: %s\n", error.message); } mongoc_stream_close(file_stream); mongoc_stream_destroy(file_stream);
Recuperar información de archivos
En esta sección, puedes aprender cómo recuperar los metadatos de archivos almacenados en la colección files del bucket de GridFS. Los metadatos de un archivo contienen información sobre el archivo al que se refieren, incluyendo:
El
_iddel archivoEl nombre del archivo
La longitud/tamaño del archivo
La fecha y hora de carga
Un documento
metadataen el que puedes almacenar cualquier otra información
Para recuperar archivos de un bucket GridFS, llama a la función mongoc_gridfs_bucket_find() y pasa tu bucket como parámetro. La función devuelve un cursor desde el cual puedes acceder a los resultados.
Tip
Para aprender más sobre los cursores en el controlador de C, consulta el Guía para acceder a datos desde un cursor .
Ejemplo
El siguiente ejemplo de código muestra cómo recuperar e imprimir metadatos de archivos de un bucket GridFS. Utiliza un bucle while para iterar a través del cursor devuelto y mostrar el contenido de los archivos subidos en los ejemplos de Subir archivos:
mongoc_cursor_t *cursor = mongoc_gridfs_bucket_find(bucket, bson_new(), NULL); const bson_t *file_doc; while (mongoc_cursor_next(cursor, &file_doc)) { char *json = bson_as_json(file_doc, NULL); printf("%s\n", json); bson_free(json); } mongoc_cursor_destroy(cursor);
{ "_id" : { "$oid" : "..." }, "length" : 13, "chunkSize" : 261120, "uploadDate" : { "$date" : ... }, "filename" : "my_file", "metadata" : { } } { "_id" : { "$oid" : "..." }, "length" : 13, "chunkSize" : 261120, "uploadDate" : { "$date" : ... }, "filename" : "new_file", "metadata" : { } }
La función mongoc_gridfs_bucket_find() acepta varias especificaciones de query. Puedes usar su parámetro de opciones para especificar el orden de clasificación, el número máximo de documentos a devolver y el número de documentos a omitir antes de devolverlos. Para ver una lista de opciones disponibles, consulte la documentación de la API mongoc_collection_find_with_opts().
Descargar archivos
Puedes descargar archivos de un bucket de GridFS utilizando las siguientes funciones:
mongoc_gridfs_bucket_open_download_stream()Abre un nuevo flujo de descarga desde el cual puedes leer el contenido del archivomongoc_gridfs_bucket_download_to_stream(): Guardar el archivo completo en un flujo de descarga existente
Leer desde un flujo de descarga
Puedes descargar archivos de tu base de datos MongoDB utilizando la función mongoc_gridfs_bucket_open_download_stream() para crear un flujo de descarga.
Este ejemplo utiliza un flujo de descarga para realizar las siguientes acciones:
Llama a la función
mongoc_gridfs_bucket_open_download_stream()para seleccionar un archivo GridFS con el valor_idespecificado y lo abre como un flujo legibleLlama a la función
mongoc_stream_read()para leer el contenido del archivoLlama a las funciones
mongoc_stream_close()ymongoc_stream_destroy()para cerrar y destruir el flujo de descarga que apunta al archivo.
char buf[512]; bson_value_t file_id; file_id.value_type = BSON_TYPE_OID; bson_oid_init_from_string(&file_id.value.v_oid, "66fb1b8ea0f84a74ee099e71"); bson_error_t error; mongoc_stream_t *download_stream = mongoc_gridfs_bucket_open_download_stream(bucket, &file_id, &error); if (!download_stream) { fprintf(stderr, "Failed to create download stream: %s\n", error.message); } mongoc_stream_read(download_stream, buf, 1, 1, 0); mongoc_stream_close(download_stream); mongoc_stream_destroy(download_stream);
Nota
Si hay varios documentos con el mismo nombre de archivo, GridFS transmitirá el archivo más reciente con el nombre dado (según lo determinado por el campo uploadDate).
Descargar en una transmisión existente
Puedes descargar el contenido de un archivo GridFS a un flujo existente llamando a la función mongoc_gridfs_bucket_download_to_stream().
Este ejemplo realiza las siguientes acciones:
Llama a la función
mongoc_stream_file_new_for_path()para abrir un archivo ubicado en/path/to/output_filecomo un flujo en modo de lectura y escritura (O_RDWR)Descarga un archivo GridFS que tiene el valor especificado
_idal flujoLlama a las funciones
mongoc_stream_close()ymongoc_stream_destroy()para cerrar y destruir el flujo de archivos
mongoc_stream_t *file_stream = mongoc_stream_file_new_for_path("/path/to/output_file", O_RDWR, 0); bson_error_t error; if (!file_stream) { fprintf(stderr, "Error opening file stream: %s\n", error.message); } bson_value_t file_id; file_id.value_type = BSON_TYPE_OID; bson_oid_init_from_string(&file_id.value.v_oid, "66fb1b8ea0f84a74ee099e71"); if (!mongoc_gridfs_bucket_download_to_stream(bucket, &file_id, file_stream, &error)) { fprintf(stderr, "Failed to download file: %s\n", error.message); } mongoc_stream_close(file_stream); mongoc_stream_destroy(file_stream);
Borrar archivos
Utiliza la función mongoc_gridfs_bucket_delete_by_id() para remover el documento de colección de un archivo y los fragmentos asociados de tu bucket. Esto borra efectivamente el archivo.
El siguiente ejemplo le muestra cómo borrar un archivo haciendo referencia a su campo _id:
bson_error_t error; bson_oid_t oid; bson_oid_init_from_string(&oid, "66fb1b365fd1cc348b031b01"); if (!mongoc_gridfs_bucket_delete_by_id(bucket, &oid, &error)) { fprintf(stderr, "Failed to delete file: %s\n", error.message); }
Nota
Revisiones de archivos
La función mongoc_gridfs_bucket_delete_by_id() admite la eliminación de solo un archivo a la vez. Si deseas borrar cada revisión de archivo o archivos con diferentes tiempos de carga que compartan el mismo nombre de archivo, recopila los valores _id de cada revisión. Luego, pase cada valor _id en llamadas por separado a la función mongoc_gridfs_bucket_delete_by_id().
Documentación de la API
Para obtener más información sobre cómo utilizar el controlador C para almacenar y recuperar archivos grandes, consulta la siguiente documentación de la API: