Docs 菜单
Docs 主页
/ / /
C#/.NET
/

存储大文件

在此页面上

  • Overview
  • GridFS 的工作原理
  • 创建 GridFS 存储桶
  • 自定义存储桶
  • 上传文件
  • 写入上传流
  • 上传现有流
  • 下载文件
  • 从下载流中读取
  • 下载到现有流
  • 查找文件
  • 删除文件
  • API 文档

在本指南中,您可以学习;了解如何使用GridFS在MongoDB中存储和检索大文件。 GridFS存储系统在存储文件时将文件拆分为数据段,并在检索文件时重新组合这些文件。 GridFS驱动程序的实施是一个抽象,用于管理文件存储的操作和组织。

如果任何文件的大小超过16 MB 的BSON文档大小限制,请使用GridFS 。有关GridFS是否适合您的使用案例的更多详细信息,请参阅MongoDB Server手册中的 GridFS 。

GridFS 在存储桶中组织文件,存储桶是一组包含文件数据段及其描述信息的MongoDB 集合。存储桶包含了以下集合:

  • chunks:存储二进制文件段

  • files:存储文件元数据

当您首次向 GridFS 存储桶写入数据时,驾驶员会创建GridFS存储桶(如果尚不存在)。存储桶包含以默认存储桶名称 fs 为前缀的 chunksfiles 集合,除非您指定了其他名称。为了确保有效检索文件和相关元数据,驾驶员会在每个集合上创建一个索引。在对GridFS存储桶执行写入操作之前,驾驶员会确保这些索引存在。

有关GridFS索引的更多信息,请参阅MongoDB Server手册中的GridFS索引。MongoDB Server

使用GridFS存储文件时,驾驶员会将文件分割成较小的数据段,每个数据段由 chunks集合中的单独文档表示。它还在 files集合中创建一个文档,其中包含文件ID、文件名和其他文件元数据。

下图展示了GridFS在上传到存储桶时如何分割文件:

显示 GridFS 如何将文件上传到存储桶的图表

在检索文件时,GridFS 从指定存储桶上的 files 集合中获取元数据,并使用该信息通过 chunks 集合中的文档重建文件。

要开始使用GridFS存储或检索文件,请创建 GridFSBucket 类的新实例,传入表示数据库的 IMongoDatabase对象。此方法访问现有存储桶,如果不存在,则创建新存储桶。

以下示例为 db数据库创建了 GridFSBucket 类的新实例:

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

您可以通过将 GridFSBucketOptions 类的实例传递给 GridFSBucket() 构造函数来自定义GridFS存储桶配置。下表描述了 GridFSBucketOptions 类中的属性:

字段
说明

BucketName

用作文件和数据段集合前缀的存储桶名称。默认值为 "fs"

数据类型string

ChunkSizeBytes

数据块将文件分割成的GridFS大小。默认值为 255 KB。

数据类型integer

ReadConcern

用于存储桶操作的读关注(read concern)。默认值为数据库的读关注(read concern)。

数据类型:ReadConcern

ReadPreference

用于存储桶操作的读取偏好(read preference)。默认值为数据库的读取偏好(read preference)。

数据类型ReadPreference

WriteConcern

用于存储桶操作的写关注(write concern)。默认值为数据库的写关注(write concern)。

数据类型写关注

以下示例通过将 GridFSBucketOptions 类的实例传递给 GridFSBucket() 构造函数来创建名为 "myCustomBucket" 的存储桶:

var options = new GridFSBucketOptions { BucketName = "myCustomBucket" };
var customBucket = new GridFSBucket(database, options);

您可以使用以下方法将文件上传到GridFS存储桶:

  • OpenUploadStream()OpenUploadStreamAsync():打开新的上传流,您可以向其中写入文件内容

  • UploadFromStream()UploadFromStreamAsync():将现有流的内容上传到GridFS文件

以下部分介绍如何使用这些方法。

使用 OpenUploadStream()OpenUploadStreamAsync() 方法为给定文件名创建上传流。这些方法接受以下参数:

Parameter
说明

filename

要上传的文件的名称。

数据类型string

options

可选。指定上传流配置的GridFSUploadOptions 类的实例。默认值为null

数据类型:GridFSUploadOptions

cancellationToken

可选。可用于取消操作的令牌。

数据类型:CancellationToken

此代码示例演示如何通过执行以下步骤来打开上传流:

  • 调用 OpenUploadStream() 方法为名为 "my_file" 的文件打开可写GridFS流

  • 调用 Write() 方法以写入my_file

  • 调用 Close() 方法关闭指向 my_file 的流

选择 SynchronousAsynchronous标签页以查看相应的代码:

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

要自定义上传流配置,请将 GridFSUploadOptions 类的实例传递给 OpenUploadStream()OpenUploadStreamAsync() 方法。 GridFSUploadOptions 类包含以下属性:

属性
说明

BatchSize

每个批处理中要上传的数据段数。默认值为 16 MB 除以 ChunkSizeBytes属性的值。

数据类型int?

ChunkSizeBytes

除最后一个数据段数据块之外的每个数据段的大小。默认值为 255 KB。

数据类型int?

Metadata

要与文件一起存储的元数据,包括以下元素:

  • 文件的 _id

  • 文件的名称

  • 文件的长度和大小

  • 上传日期和时间

  • 可以在其中存储其他信息的 metadata文档

默认值为 null

数据类型:BsonDocument

以下示例执行与前一示例相同的步骤,但也使用 ChunkSizeBytes 选项指定每个数据段的数据块。选择 SynchronousAsynchronous标签页以查看相应的代码。

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

使用 UploadFromStream()UploadFromStreamAsync() 方法将流的内容上传到新的GridFS文件。这些方法接受以下参数:

Parameter
说明

filename

要上传的文件的名称。

数据类型string

source

要从中读取文件内容的流。

数据类型:流

options

可选。指定上传流配置的GridFSUploadOptions 类的实例。默认值为null

数据类型:GridFSUploadOptions

cancellationToken

可选。可用于取消操作的令牌。

数据类型:CancellationToken

此代码示例演示如何通过执行以下步骤来打开上传流:

  • 以二进制读取模式将位于 /path/to/input_file 的文件作为流打开

  • 调用 UploadFromStream() 方法将流的内容写入名为 "new_file" 的GridFS文件

选择 SynchronousAsynchronous 标签页,查看相应的代码。

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

您可以使用以下方法从GridFS存储桶下载文件:

  • OpenDownloadStream()OpenDownloadStreamAsync():打开新的下载流,您可以从中读取文件内容

  • DownloadToStream()DownloadToStreamAsync():将GridFS文件的内容写入现有流

以下部分更详细地描述了这些方法。

使用 OpenDownloadStream()OpenDownloadStreamAsync() 方法创建下载流。这些方法接受以下参数:

Parameter
说明

id

要下载的文件的 _id 值。

数据类型:BsonValue

options

可选。指定下载流配置的GridFSDownloadOptions 类的实例。默认值为null

数据类型:GridFSDownloadOptions

cancellationToken

可选。可用于取消操作的令牌。

数据类型:CancellationToken

以下代码示例演示了如何通过执行以下步骤来打开下载流:

  • 检索名为 "new_file" 的GridFS文件的 _id

  • 调用 OpenDownloadStream() 方法并传递 _id 值以将文件作为可读GridFS流打开

  • 创建一个 buffer 向量来存储文件内容

  • 调用 Read() 方法将文件内容从 downloader流读入向量

选择 SynchronousAsynchronous 标签页,查看相应的代码。

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
}
}

要自定义下载流配置,请将 GridFSDownloadOptions 类的实例传递给 OpenDownloadStream() 方法。 GridFSDownloadOptions 类包含以下属性:

属性
说明

Seekable

指示流是否支持查找、查询和更改流中当前位置的能力。默认值为false

数据类型bool?

以下示例执行与前面的示例相同的步骤,但还将 Seekable 选项设置为 true 以指定该流是可查找的。

选择 SynchronousAsynchronous 标签页,查看相应的代码。

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
}
}

使用 DownloadToStream()DownloadToStreamAsync() 方法将GridFS文件的内容下载到现有流。这些方法接受以下参数:

Parameter
说明

id

要下载的文件的 _id 值。

数据类型:BsonValue

destination

.NET/ C#驱动程序将GridFS文件下载到的流。此属性的值必须是实现 Stream 类的对象。

数据类型:流

options

可选。指定下载流配置的GridFSDownloadOptions 类的实例。默认值为null

数据类型:GridFSDownloadOptions

cancellationToken

可选。可用于取消操作的令牌。

数据类型:CancellationToken

以下代码示例演示了如何通过执行以下操作来下载到现有流:

  • 以二进制写入模式将位于 /path/to/output_file 的文件作为流打开

  • 检索名为 "new_file" 的GridFS文件的 _id

  • 调用 DownloadToStream() 方法并传递 _id 值,以将 "new_file" 的内容下载到流

选择 SynchronousAsynchronous 标签页,查看相应的代码。

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

要查找GridFS存储桶中的文件,请对 GridFSBucket实例调用 Find()FindAsync() 方法。这些方法接受以下参数:

Parameter
说明

filter

查询过滤,用于指定 files集合中要匹配的条目。

数据类型:FilterDefinition<GridFSFileInfo> 。有关更多信息,请参阅 Find() 方法的API文档。

source

要从中读取文件内容的流。

数据类型:流

options

可选。 GridFSFindOptions类的实例,用于指定查找操作的配置。默认值为null

数据类型:GridFSFindOptions

cancellationToken

可选。可用于取消操作的令牌。

数据类型:CancellationToken

以下代码示例演示如何从GridFS存储桶中的文件检索和打印文件元数据。Find() 方法返回一个IAsyncCursor<GridFSFileInfo> 实例,您可以从该实例访问权限结果。它使用foreach 循环遍历返回的游标,并显示上传文件示例中上传的文件的内容。

选择 SynchronousAsynchronous 标签页,查看相应的代码。

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" }

要自定义查找操作,请将 GridFSFindOptions 类的实例传递给 Find()FindAsync() 方法。 GridFSFindOptions 类包含以下属性:

属性
说明

Sort

结果的排序顺序。 如果未指定排序顺序,该方法将按插入顺序返回结果。

数据类型:SortDefinition<GridFSFileInfo> 。有关更多信息,请参阅 Sort属性的API文档。

要从GridFS存储桶中删除文件,请在 GridFSBucket实例上调用 Delete()DeleteAsync() 方法。此方法会从存储桶中删除文件的元数据集合及其关联的数据段。

DeleteDeleteAsync() 方法接受以下参数:

Parameter
说明

id

要删除的文件的_id

数据类型:BsonValue

cancellationToken

可选。可用于取消操作的令牌。

数据类型:CancellationToken

以下代码示例展示了如何将名为 "my_file" 的文件的 _id 值传递给 delete_file() 来删除该文件:

  • 使用 Builders 类创建与名为 "my_file" 的文件匹配的过滤

  • 使用 Find() 方法查找名为 "my_file" 的文件

  • 将文件的 _id 值传递给 Delete() 方法以删除文件

选择 SynchronousAsynchronous 标签页,查看相应的代码。

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

注意

文件修订

Delete()DeleteAsync() 方法一次仅支持删除一个文件。如果要删除每个文件修订版本,或上传时间不同但股票相同文件名的文件,请收集每个修订版本的 _id 值。然后,将每个 _id 值分别传递给 Delete()DeleteAsync() 方法。

要学习;了解有关此页面上使用的类的更多信息,请参阅以下API文档:

要详细学习;了解此页面上使用的 GridFSBucket 类中的方法,请参阅以下API文档:

后退

按地理空间搜索