.NET MongoDB Driver GridFS 2.2原理及使用示例


一、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 GridFSUploadOptionsGridFS上傳操作選項

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. 下述操作中的參數列表中,idfiles_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.filesfs.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 = 0//指定版本
            };
            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 =1024,
};

Firstbucket為新的名稱,默認的名稱為fs

 

-----------------------------------------------------------------------------------------

轉載與引用請注明出處。

時間倉促,水平有限,如有不當之處,歡迎指正。

我的博客即將搬運同步至騰訊雲+社區,邀請大家一同入駐:https://cloud.tencent.com/developer/support-plan


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM