zoukankan      html  css  js  c++  java
  • mongoDB学习笔记——存取图片(C#)

    作为一个NoSql数据库的代表,存取多媒体数据,应该是强项吧?那么,图片在mongoDB里是如何存取的呢?(其实,关系型数据库存取图片也一点问题没有,所以我看NoSql的强项不在于是否存储多媒体,而在于采用键值对的方式来存储数据。)


    mongoDB存取图片有两种方式:

    "由于MongoDB的文档结构为BJSON格式(BJSON全称:Binary JSON),而BJSON格式本身就支持保存二进制格式的数据,因此可以把文件的二进制格式的数据直接保存到MongoDB的文档结构中。但是由于一个BJSON的最大长度不能超过4M,所以限制了单个文档中能存入的最大文件不能超过4M。为了提供对大容量文件存取的支持,samus驱动提供了“GridFS”方式来支持,“GridFS”方式文件操作需要引入新的程序集“MongoDB.GridFS.dll”。"


    一、在文档对象中存取文件

      当文件大小较小的时候,直接存入文档对象实现起来更简洁。比如大量图片文件的存取等,一般图片文件都不会超过4M。我们先实现一个上传图片存入数据库,再取出来写回页面的例子:



    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    using System.IO;
    
    using MongoDB.Bson;
    using MongoDB.Driver;
    
    namespace mongotest
    {
        public partial class Form3 : Form
        {
            public Form3()
            {
                InitializeComponent();
                Init();
            }
            //数据库连接字符串
            const string strconn = "mongodb://127.0.0.1:27017";
            //数据库名称
            const string dbName = "test";
            MongoServer server;
            MongoDatabase db;
            void Init()
            {
                //创建数据库链接
                server = MongoDB.Driver.MongoServer.Create(strconn);
                //获得数据库
                db = server.GetDatabase(dbName);
            }
            private void SaveImgBJSON(byte[] byteImg)
            {
                BsonDocument doc = new BsonDocument();
    
                doc["ID"] = 1;
                doc["Img"] = byteImg;
    
                MongoCollection col = db.GetCollection("thins");
                col.Save(doc);
            }
            private void btnSaveImg_Click(object sender, EventArgs e)
            {
                byte[] byteImg = File.ReadAllBytes(@"c:	empyl.jpg");
                SaveImgBJSON(byteImg);
            }
            private void btnShowImg_Click(object sender, EventArgs e)
            {
                MongoCollection col = db.GetCollection("thins");
                var query = new QueryDocument { { "ID", 1} };
                var result = col.FindAs<BsonDocument>(query);
                byte[] buff = (byte[])((BsonDocument)result.ToList()[0]).GetValue("Img");
                MemoryStream MS = new MemoryStream(buff);
                pictureBox1.Image = Image.FromStream(MS);
            }
        }
    }
    

    二、用GridFS方式存取文件


      在实现GridFS方式前我先讲讲它的原理,为什么可以存大文件。驱动首先会在当前数据库创建两个集合:"fs.files"和"fs.chunks"集合,前者记录了文件名,文件创建时间,文件类型等基本信息;后者分块存储了文件的二进制数据(并支持加密这些二进制数据)。分块的意思是把文件按照指定大小分割,然后存入多个文档中。"fs.files"怎么知道它对应的文件二进制数据在哪些块呢?那是因为在"fs.chunks"中有个"files_id"键,它对应"fs.files"的"_id"。"fs.chunks"还有一个键(int型)"n",它表明这些块的先后顺序。这两个集合名中的"fs"也是可以通过参数自定义的。

    (我想起了Sql Server的FileStream)


      如果你只是想知道怎么用,可以忽略上面这段话,下面将用法:

    这里引用了两个第三方dll,可以到https://github.com/samus/mongodb-csharp下载,编译后得到。


    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    using System.IO;
    
    using MongoDB;
    using MongoDB.GridFS;
    
    namespace mongotest
    {
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
                Init();
            }
            private void btnGridFSSave_Click(object sender, EventArgs e)
            {
                byte[] byteImg = File.ReadAllBytes(@"c:	empyl.jpg");
                filename = GridFsSave(byteImg);
                MessageBox.Show(filename);
            }
            private void btnGridFSShow_Click(object sender, EventArgs e)
            {
                byte[] buff = GridFsRead(filename);
                MemoryStream MS = new MemoryStream(buff);
                pictureBox1.Image = Image.FromStream(MS);
            }
            private Mongo mongo;
            private IMongoDatabase test;
            string filename;
            void Init()
            {
                var connstr = @"Server=localhost:27017";
                mongo = new Mongo(connstr);
                mongo.Connect();
                test = mongo["test"];
            }
            private string GridFsSave(byte[] byteFile)
            {
                string filename = Guid.NewGuid().ToString();
    
                //这里GridFile构造函数有个重载,bucket参数就是用来替换那个创建集合名中默认的"fs"的。
                GridFile gridFile = new GridFile(test);
                using (GridFileStream gridFileStream = gridFile.Create(filename))
                {
                    gridFileStream.Write(byteFile, 0, byteFile.Length);
                }
                return filename;
            }
            private byte[] GridFsRead(string filename)
            {
                GridFile gridFile = new GridFile(test);
                GridFileStream gridFileStream = gridFile.OpenRead(filename);
                byte[] bytes = new byte[gridFileStream.Length];
                gridFileStream.Read(bytes, 0, bytes.Length);
                return bytes;
            }
        }
    }
    

    存储在数据库中如图:



    参考文章:

    http://www.cnblogs.com/lipan/archive/2011/03/21/1989409.html

  • 相关阅读:
    TCP粘包,产生的原因以及解决方案
    php判断变量是否为正整数
    php函数trim中文编码问题解决
    win10设置开机自动启动vagrant虚拟机
    Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
    git push 时 fatal: Unable to create 'D:/phpStudy/WWW/green_tree/.git/index.lock': File exists.解决办法
    git push 提示 Everything up-to-date
    Allowed memory size of 134217728 bytes exhausted (tried to allocate 2 bytes)
    访问远程mysql数据库,出现报错,显示“1130
    改变网页选中文本的颜色
  • 原文地址:https://www.cnblogs.com/leftfist/p/4257957.html
Copyright © 2011-2022 走看看