MongoDB
GridFS
C#
File Storage
Image Handling

MongoDB GridFs with C, how to store files such as images?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

MongoDB GridFS is a specification for storing and retrieving files that exceed the BSON-document size limit of 16 MB. It's particularly useful for storing large files such as images, videos, and other types of media, or for storing many small files. This article delves into how to implement GridFS using C#, offering technical explanations and examples on how to effectively store files like images into a MongoDB database using this powerful tool.

MongoDB GridFS

GridFS is a storage specification within MongoDB used for handling large files by dividing them into chunks and storing each chunk as a separate document in MongoDB. Here’s how it operates:

  • Files are split into chunks of configurable size, default is 255 KB.
  • Each chunk is stored as a separate document in two collections: fs.chunks and fs.files.
  • The fs.files collection stores metadata of the file, including its name and length.
  • The fs.chunks collection stores the binary data chunks.

Setting Up C# Environment for MongoDB

To interact with MongoDB in a C# application, you'll need to include the MongoDB driver. You can add it to your project using NuGet Package Manager as follows:

bash
Install-Package MongoDB.Driver

Basic GridFS Operations

Once the MongoDB driver is set up, you can proceed with the basic operations: storing and retrieving files using GridFS. Below are steps to perform these operations:

Storing an Image File

To store an image using MongoDB GridFS in a C# application, follow these steps:

  1. Initialize MongoDB Client, Database, and GridFS Bucket
csharp
1   using MongoDB.Driver;
2   using MongoDB.Bson;
3   using MongoDB.Bson.Serialization.Attributes;
4   using MongoDB.Driver.GridFS;
5   using System.IO;
6   using System.Threading.Tasks;
7   
8   var client = new MongoClient("your_mongodb_connection_string");
9   var database = client.GetDatabase("your_database_name");
10   var bucket = new GridFSBucket(database);
  1. Upload the Image File
    Plain and simple, read the file into a byte array and upload it:
csharp
1   byte[] imageData = File.ReadAllBytes("path_to_your_image.jpg");
2   
3   var fileId = await bucket.UploadFromBytesAsync("image.jpg", imageData);
4   Console.WriteLine($"Image uploaded with ID: {fileId}");

Retrieving an Image File

Retrieving the file involves downloading the binary data from GridFS:

  1. Download the Image Data
csharp
   var fileBytes = await bucket.DownloadAsBytesByNameAsync("image.jpg");
   File.WriteAllBytes("downloaded_image.jpg", fileBytes);
   Console.WriteLine("Image has been downloaded.");
  1. Using Stream for Large Files
    If you're dealing with particularly large files, streaming the data might be more efficient:
csharp
1   using (var stream = await bucket.OpenDownloadStreamAsync(fileId))
2   {
3       using (var fileStream = File.Create("downloaded_large_image.jpg"))
4       {
5           await stream.CopyToAsync(fileStream);
6       }
7   }
8   Console.WriteLine("Large image has been downloaded.");

Managing Metadata

GridFS allows you to store additional metadata with your files:

  1. Add Metadata during Upload
csharp
1   var options = new GridFSUploadOptions
2   {
3       Metadata = new BsonDocument
4       {
5           { "content-type", "image/jpeg" },
6           { "upload_date", BsonDateTime.Create(DateTime.UtcNow) }
7       }
8   };
9   
10   var fileIdWithMetadata = await bucket.UploadFromBytesAsync("meta_image.jpg", imageData, options);
  1. Retrieve Metadata
    Metadata can be accessed later by querying the fs.files collection.
csharp
1   var filesCollection = database.GetCollection<BsonDocument>("fs.files");
2   var filter = Builders<BsonDocument>.Filter.Eq("filename", "meta_image.jpg");
3   var fileDoc = await filesCollection.Find(filter).FirstOrDefaultAsync();
4   
5   Console.WriteLine($"Metadata: {fileDoc["metadata"]}");

Best Practices and Considerations

Chunk Size Configuration

  • The default chunk size is 255 KB. Adjust based on your needs:
csharp
1   var options = new GridFSBucketOptions
2   {
3       ChunkSizeBytes = 1024 * 512  // 512 KB for example
4   };
5   var customBucket = new GridFSBucket(database, options);

Error Handling

  • Implement error handling to manage scenarios like failed uploads or downloads:
csharp
1  try
2  {
3      // Attempt to download/upload
4  }
5  catch (GridFSException ex)
6  {
7      Console.WriteLine($"GridFS Error: {ex.Message}");
8  }

Summary Table

FeatureDetails
Default Chunk Size255 KB
Collectionsfs.chunks, fs.files
Supported File TypesBinary files (images, videos, etc.)
MetadataCustomizable via BsonDocument
Error HandlingRecommended using GridFSException

Conclusion

MongoDB GridFS in C# offers a robust way to handle large file storage directly in your database, providing ease of retrieval and enhanced metadata support. Its straightforward API and scalability make it an ideal choice for applications that require efficient media handling.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.