一、API解讀
1 GridFSBucketOptions
1)public string BucketName { get; set; }
獲取或設定bucket名稱
2)public int ChunkSizeBytes { get; set; }
獲取或設定塊的位元組大小
3)public ReadConcern ReadConcern { get; set; }
獲取或設定讀關注
4)public ReadPreference ReadPreference { get; set; }
獲取或設定讀優先權
1)public WriteConcern WriteConcern { get; set; }
獲取或設定寫關注
2 GridFSUploadOptions:GridFS上傳操作選項
1)[Obsolete("Place aliases inside metadata instead.")]
public IEnumerable<string> Aliases { get; set; }
(已不再使用)獲取或設定別名
2)public int? BatchSize { get; set; }
獲取或設定一堆的大小
1) public int? ChunkSizeBytes { get; set; }
獲取或設定塊的位元組大小
4)[Obsolete("Place contentType inside metadata instead.")]
public string ContentType { get; set; }
(已不再使用)獲取或設定資源型別
5)public BsonDocument Metadata { get; set; }
獲取或設定元資料
3 GridFSDownloadOptions:下載操作選項
1)public bool? CheckMD5 { get; set; }
獲取或設定是否檢驗MD5值
2)public bool? Seekable { get; set; }
獲取或設定返回流是否支援查詢
4 GridFSFindOptions:查詢選項
public SortDefinition<GridFSFileInfo> Sort { get; set; }
獲取或設定排序
5 GridFSFileInfo
儲存在資料庫中的一個GridFS檔案的資訊
1)public BsonDocument BackingDocument { get; }
獲得支援檔案
2)public int ChunkSizeBytes { get; }
獲得塊大小
3)public string Filename { get; }
獲得檔名
4)public ObjectId Id { get; }
獲得標識
5)public long Length { get; }
獲得檔案長度
6)public string MD5 { get; }
獲得MD5值
7)public BsonDocument Metadata { get; }
獲得元資料
8)public DateTime UploadDateTime { get; }
獲得上傳時間
6 GridFSBucket
說明:
- 下述操作中的引數列表中,id為files_id的值,而不是_id的值
- 有的操作有相應的非同步方法,這裡沒有列出
- 當多個檔案的檔名相同時,可以通過指定版本來選擇下載哪一個檔案,預設的是-1(最新上傳的版本),0表示原始版,1表示第一個版本,2...依次類推;-1表示最新版本,-2表示次新版本,-3...依次類推
1)public GridFSBucket(IMongoDatabase database, GridFSBucketOptions options = null);
建構函式
引數:
database:待操作資料庫
options :構造GridFS例項的選項
2)public ObjectId UploadFromBytes(string filename, byte[] source, GridFSUploadOptions options = null, CancellationToken cancellationToken = null)
上傳操作
引數:
filename:檔名
source:待上傳資源
options :上傳選項
cancellationToken :傳播有關應取消操作的通知
3)public Task<ObjectId> UploadFromBytesAsync(string filename, byte[] source, GridFSUploadOptions options = null, CancellationToken cancellationToken
非同步上傳操作
引數同2)
4)public ObjectId UploadFromStream(string filename, Stream source, GridFSUploadOptions options = null, CancellationToken cancellationToken = null);
上傳操作
引數同2)
4)public Task<ObjectId> UploadFromStreamAsync(string filename, Stream source, GridFSUploadOptions options = null, CancellationToken cancellationToken = null);
上傳操作
引數同2)
5)public GridFSUploadStream OpenUploadStream(string filename, GridFSUploadOptions options = null, CancellationToken cancellationToken = null);
上傳操作
引數:
filename:檔名
options :上傳選項
cancellationToken :傳播有關應取消操作的通知
返回值:
流,通過此流將資料寫入GridFS
5)public byte[] DownloadAsBytes(BsonValue id, GridFSDownloadOptions options = null, CancellationToken cancellationToken = null);
下載操作
引數:
id:檔案id,注意這個是files_id的值,而不是_id的值
options :下載選項
cancellationToken :傳播有關應取消操作的通知
7)public void DownloadToStream(BsonValue id, Stream destination, GridFSDownloadOptions options = null, CancellationToken cancellationToken = null);
下載操作
引數:
id:檔案id,注意這個是files_id的值,而不是_id的值
destination:目標流
options :下載選項
cancellationToken :傳播有關應取消操作的通知
8)public void DownloadToStreamByName(string filename, Stream destination, GridFSDownloadByNameOptions options = null, CancellationToken cancellationToken = null);
下載操作
引數:
filename:檔名
destination:目標流
options :下載選項
cancellationToken :傳播有關應取消操作的通知
9)public IAsyncCursor<GridFSFileInfo> Find(FilterDefinition<GridFSFileInfo> filter, GridFSFindOptions options = null, CancellationToken cancellationToken = null);
查詢操作
引數
Filter:查詢過濾器
options :查詢選項
cancellationToken :傳播有關應取消操作的通知
10)public void Delete(BsonValue id, CancellationToken cancellationToken = null);
刪除一個檔案
引數:
id:檔案id,注意這個是files_id的值,而不是_id的值
cancellationToken :傳播有關應取消操作的通知
11)public void Drop(CancellationToken cancellationToken = null);
刪除整個chunks
12)public void Rename(BsonValue id, string newFilename, CancellationToken cancellationToken = null);
重新命名操作
引數:
id:檔案id,注意這個是files_id的值,而不是_id的值
newFilename:新檔名
cancellationToken :傳播有關應取消操作的通知
二、操作例項
GridFS簡介
MongodB使用兩個集合來儲存GridFS檔案,一個是fs.files,另一個是fs.chunks。
fs.files這個集合中儲存的是每一個上傳到資料庫的文件的資訊。
fs.chunks這個集合儲存的是上傳檔案的內容。一個chunk相當於一個文件。
GridFS中的bucket這個概念指代的是fs.files和fs.chunks的組合。
使用Robmongo只能看到fs.files的部分結構為:
{
"_id" : ObjectId("5a6559cd379d581bc00b0921"),
"length" : NumberLong(25822),
"chunkSize" : 261120,
"uploadDate" : ISODate("2018-01-22T03:26:05.327Z"),
"md5" : "03c50390b953913428daeb11c6a31b8f",
"filename" : "gridfsTest"
}
其中
_id:此文件唯一標識
length:檔案長度
uploadDate:檔案上傳日期
md5:完整檔案的MD5
filename:檔名
未列出的欄位包括:
contentType:字串型別,檔案的MIME型別
aliases:陣列型別,別名集合
metadata:任意型別,使用者想存入的附加資訊
使用Robmongo檢視fs.chunks的結構為:
{
"_id" : ObjectId("5a656bf4379d5820fcd60412"),
"files_id" : ObjectId("5a656bf4379d5820fcd60411"),
"n" : 0,
"data" : { "$binary" : "suLK1MnPtKvX1r3ayv3X6Q==", "$type" : "00" }
}
其中:
_id:一個塊(文件)的唯一標識。
files_id:源文件的唯一標識,用來區別集合中的檔案。
n:塊的序號,從0開始。GridFS中每一塊的大小可以設定,預設是255KB,當上傳的檔案大於設定的或預設的塊大小時,會將檔案切分成幾塊進行儲存,但最後一塊可能比設定的值或預設值大。
例如上傳一個296KB的檔案,預設塊大小,發現包含兩塊,fs.chunks中的文當結構
而在fs.files中對應著一個文件,指明瞭上傳檔案的總大小
data:檔案內容
客戶端封裝
說明:
展示部分程式碼段,對GridFS操作的封裝大體相同,可根據實際情況修改。
呼叫方式統一採用:
/// <summary>
/// MongoDB操作
/// </summary>
public class MongoDBService
{
#region 變數
/// <summary>
/// 快取
/// </summary>
private static ConcurrentDictionary<string, Lazy<MongoClient>> m_mongoClientCache =
new ConcurrentDictionary<string, Lazy<MongoClient>>();
/// <summary>
/// 連線字串
/// </summary>
private string m_connectionStr = string.Empty;
/// <summary>
/// 資料庫名稱
/// 支援執行時更改
/// </summary>
public string DatabaseName { get; set; }
/// <summary>
/// 設定GridFS引數
/// </summary>
public GridFSBucketOptions BucksOptions { get; set; }
#endregion /// <summary>
/// 初始化操作
/// </summary>
public MongoDBService(string connStr, string database)
{
m_connectionStr = connStr;
DatabaseName = database;
} /// <summary>
/// 獲得Mongo客戶端
/// </summary>
/// <param name="connStr">連線串</param>
/// <returns></returns>
private static MongoClient GetClient(string connStr)
{
if (string.IsNullOrWhiteSpace(connStr)) throw new ArgumentException("MongoDB Connection String is Empty"); return m_mongoClientCache.GetOrAdd(connStr,
new Lazy<MongoClient>(() =>
{
return new MongoClient(connStr);
})).Value;
}
......
public ObjectId UploadFromBytes(byte[] source, string fileName, GridFSUploadOptions options=null)
{
MongoClient client = GetClient(m_connectionStr);
var db = client.GetDatabase(DatabaseName);
var bucket = new GridFSBucket(db, BucksOptions);
return bucket.UploadFromBytes(fileName, source, options);
}
......
}
1上傳
//讀取本地檔案,然後上傳
using (FileStream sr = new FileStream(@"D:\gridfsTest.jpg", FileMode.Open))
{ mongoDBService.UploadFromStream(sr, "gridfsTest", null);
}
//上傳位元組陣列
string str = "測試上傳位元組陣列";
byte[] b = Encoding.Default.GetBytes(str);
mongoDBService.UploadFromBytes(b, "gridfsTest");
//換一種方式
mongoDBService.UploadToStream(b, "gridfsTest");
2下載
//寫入本地檔案
using(FileStream fs = new FileStream(@"D:\gridfsDownload.jpg", FileMode.Create))
{
mongoDBService.DownloadToStream(new ObjectId("5a61a113379d582f14e750a3"), fs);
} //獲取檔案內容
var b = mongoDBService.DownloadAsBytes(new ObjectId("5a61b103379d5829f89d0688"));
Console.WriteLine(Encoding.Default.GetString(b)); //非同步方法
var bs = mongoDBService.DownloadAsBytesAsync(new ObjectId("5a61b103379d5829f89d0688"));
bs.Wait();
Console.WriteLine("非同步的方法,獲得的字串為:" + Encoding.Default.GetString(bs.Result)); //使用檔名下載
var options = new GridFSDownloadByNameOptions
{
Revision = //指定版本
};
using (FileStream fs = new FileStream(@"D:\gridfsDownloadByName.jpg", FileMode.Create))
{
mongoDBService.DownloadToStreamByName("gridfsTest", fs,options);
}
3 查詢
//可以選擇排序方式
var filter = Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, "gridfsTestNewName1");
var info = mongoDBService.Find(filter);
4重新命名和刪除
//改一個檔案
mongoDBService.RenameSingleFile(new ObjectId("5a61b103379d5829f89d0688"), "gridfsTestNewName"); //全改
var filter = Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, "gridfsTest");
mongoDBService.RenameAllRevisions("gridfsTestNewName1", filter);
//刪除指定的一個檔案
mongoDBService.DeleteSingleFile(new ObjectId("5a61a113379d582f14e750a3")); //刪除整個chunks
mongoDBService.DropEntireBucket();
5修改GridFSBucket引數
//注意ChunkSizeBytes 單位是byte
GridFSBucketOptions bucksOptions = new GridFSBucketOptions
{
BucketName = "firstbucket",
ChunkSizeBytes =,
};
Firstbucket為新的名稱,預設的名稱為fs
-----------------------------------------------------------------------------------------
轉載與引用請註明出處。
時間倉促,水平有限,如有不當之處,歡迎指正。
我的部落格即將搬運同步至騰訊雲+社群,邀請大家一同入駐:https://cloud.tencent.com/developer/support-plan