一、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

說明:

  1. 下述操作中的引數列表中,id為files_id的值,而不是_id的值
  2. 有的操作有相應的非同步方法,這裡沒有列出
  3. 當多個檔案的檔名相同時,可以通過指定版本來選擇下載哪一個檔案,預設的是-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