zoukankan      html  css  js  c++  java
  • .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

  • 相关阅读:
    Moq4在.NET3.5和.NET4版本之间的差异
    TDD中的迭代
    洛谷 3413 萌数
    割点(tarjan)
    hdu-4507 吉哥系列故事——恨7不成妻
    hdu-3709 Balanced Number
    poj-3252 Round Numbers
    hdu 1007 Quoit Design 分治求最近点对
    LA 3905 Meteor 扫描线
    uva 11464
  • 原文地址:https://www.cnblogs.com/hdwgxz/p/8335291.html
Copyright © 2011-2022 走看看