To grasp mongoDB (five) - driven by operating GridFS mongofiles and C #

1 GridFS Introduction

  The maximum size of the current Bson energy storage is 16M, 16M of files larger than we want into mongoDB in how to do it? mongoDB provided GridFS is specifically to do this. When using GridFS store large files, one file is divided into blocks (default size is 255 kb), each stored in a separate one of the document. GridFS The files are stored in the two collection: chunks collection and collection Files, wherein the collection of chunks are to save the file block, the metadata collection Files save the file.

2 Use mongofiles large file management

  mongofiles is mongoDB built-in file manipulation tool, provides a very simple API that enables us to achieve file upload, download, find and delete the command line. We use a video file to do the test.

1 upload files (put)

  We prepare the movie Green Paper (file name: "lvpishu.mkv") under the / data / videos uploaded to mongoDB database myfiles, you only need to use a command to complete the upload file: execute in the bin directory of mongoDb command    mongofiles -d myfiles the -l /data/videos/lvpishu.mkv PUT lvpishu.mkv   . After uploading using robomongo view the file information, as follows:

   Use robomongo view uploaded file information, as shown below:

2 Download file (get)

  下载GridFS中的文件使用命令Get,如我们要将刚才上传的电影,下载到/data/videos2目录下,执行命令 mongofiles -d myfiles -l /data/videos2/lvpishu.mkv get lvpishu.mkv 即可,效果如下:

3 查找文件(list、search)

  查询 GridFS中的文件可以使用search查询文件名包含某字符串的文件信息,使用list查询以某字符串开头的文件列表,因为我们只上传了一个文件所以这里的文件列表也只展示一条文件信息,执行命令效果如下:

 

4 删除文件(delete)

  如果我们想删除GridFS中的某一文件,使用delete <filename>命令

3 使用C#驱动操作GridFS

  前边我们已经使用mongoDB自带的命令行工具mongofiles实现了大文件的增删查操作,但是实际开发中我们更常用的方式是使用各种语言驱动来管理文件,这里展示怎么通过C#驱动来实现大文件的管理。添加GridFS的包 Install-Package MongoDB.Driver.GridFS ,C#驱动中提供了GridFSBucket(GridFS桶)对象来保存文件,它是fs.files和fs.chunks的组合,我们在使用时,最好使用GridFSBucket来和GridFS交互,尽量不要直接使用底层的fs.files和fs.chunks)。

  C#驱动mongoDB的上传和下载文件有两种形式:①通过字节数组byte[]上传和下载,这种方式适用于文件不大的情况,②使用stream的方式进行上传和下载,这种形式适用于各种场合,这里就采用stream的形式做文件的上传和下载演示,代码如下:

    class Program
    {
        static void Main(string[] args)
        {
            //连接数据库
            var client = new MongoClient("mongodb://192.168.70.133:27017, 192.168.70.131:27017, 192.168.70.129:27017");
            //获取database
            var mydb = client.GetDatabase("myfilesDb");
            //初始化GridFSBucket
            var bucket = new GridFSBucket(mydb, new GridFSBucketOptions
            {
                BucketName = "lvpishu",         //设置根节点名
                ChunkSizeBytes = 1024 * 1024,   //设置块的大小为1M
                WriteConcern = WriteConcern.WMajority,     //写入确认级别为majority
                ReadPreference = ReadPreference.Secondary  //优先从从节点读取
            });
            //上传文件
            //上传的配置项,可以添加文件元数据
            var options = new GridFSUploadOptions
            {
                //ChunkSizeBytes = 1048000, 
                Metadata = new BsonDocument
                {
                    { "format", "mkv" },
                    { "country", "USA" }
                }
            };
            //通过stream形式上传文件
            ObjectId fileId;
            Console.WriteLine("开始文件上传---------------->");
            string sourceFile = @"D:\迅雷下载\lvpishu.mkv";
            using (var fs = new FileStream(sourceFile, FileMode.Open))
            {
                //mongodb中的文件名为“绿皮书”
                Console.WriteLine("上传中...");
                 fileId = bucket.UploadFromStream(filename: "绿皮书", source: fs, options: options);
            }
            Console.WriteLine("<----------------文件上传完成");
            Console.WriteLine();

            //查看文件
            var filter = Builders<GridFSFileInfo>.Filter;
            
            using (var cursor = bucket.Find(filter.Eq(x => x.Filename, "绿皮书")))
            {
                var fileInfo = cursor.FirstOrDefault();
                fileId = fileInfo.Id;
                Console.WriteLine($"文件名:{fileInfo?.Filename}, 文件大小:{fileInfo?.Length}字节, 文件上传时间:{fileInfo?.UploadDateTime.AddHours(8)}");
                Console.WriteLine($"自定义的元数据:{fileInfo?.Metadata}");
            }
            Console.WriteLine();

            //下载文件
           //文件下载的位置
            Console.WriteLine("开始文件下载---------------->");
            string tagrgetPath = @"D:/mongoDownLoad/绿皮书下载.mkv";
            using (var mongoStream = bucket.OpenDownloadStream(id: fileId))
            {
                Console.WriteLine("下载中...");
                //通过FileStream写文件
                using (FileStream fsWrite = new FileStream(tagrgetPath, FileMode.Create)) 
                {
                    //开辟临时缓存内存
                    byte[] buffer = new byte[1024 * 1024]; 
                    while (true)
                    {
                        //readCount是真正读取到的字节数
                        int readCount = mongoStream.Read(buffer, 0, buffer.Length);
                        //写入目标文件
                        fsWrite.Write(buffer, 0, readCount);
                        //判断是否读取完成
                        if (readCount < buffer.Length)
                        {
                            break; 
                        }
                    }
                }
            }
            //最好比较一下mongodb中的文件和下载文件的Md5值,如果md5相同表示下载完成
            //这里为了简单起见,就简单判断以下文件是否存在
            if (File.Exists(@"D:/mongoDownLoad/绿皮书下载.mkv"))
            {
                Console.WriteLine("<----------------文件下载完成!");
            }
            Console.WriteLine();

            //删除文件
            bucket.Delete(id: fileId);
            Console.WriteLine("文件已删除!");

            Console.ReadKey();
        }
    }

  初始化GridFSBucket时可以设置一些参数:BucketName用于设置files和chunks的根节点名,如设置BucketName="lvpishu",那么在数据库中保存文件的两个collection的名字为lvpishu.files和lvpishu.chunks。ChunkSizeBytes用于设置数据块的大小,这里设置数据块大小为1M。

代码的注释比较详细,这里就不多介绍了,程序运行结果如下:

小结   

  本节介绍了GridFS的概念,并简单演示了怎样使用mongofile和C#驱动进行大文件的上传、查询、下载、删除操作。如果文中有错误的话,希望大家可以指出,我会及时修改,谢谢!

 

  

 

Guess you like

Origin www.cnblogs.com/wyy1234/p/11048130.html