C#使用MongoDb來隱藏檔

來源:互聯網
上載者:User

標籤:color   簡單   async   contains   集合   取圖   rmi   mongodb   顯示   

近期在寫一個小玩意,需要儲存一些圖片,以前我採用的是FTP或者直接資料庫儲存檔案,用FTP來儲存檔案感覺比較麻煩,用資料庫吧,還要改欄位類型,修改代碼,修改查詢語句,懶得改。

以前看過mongonDb的文章,隨就打算用Mongon來隱藏檔,然後打算百度一下看看,C#操作mongoDb的文章,全是互相抄襲,而且年代久遠,很多東西mongoDb都沒有了,隨就魔法上網。

不在介紹MongoDb是什麼,怎麼安裝,具體百度

一:使用前準備1:安裝MongoDb,百度安裝 ,並下載任意一個mongonDb的可視化軟體

我mongoDb是裝在的linux伺服器上,具體的安裝平台有讀者自己決定

可視乎軟體我推薦Robo

2:建立一個winfrom項目

右鍵項目Nuget包管理器,下載

安裝這兩個包

二:檔案上傳

這裡先用圖片來做測試

mongonDb有2種方式來儲存,1:普通的document來隱藏檔,最大為16MB,2:gridFs儲存,

1:普通document儲存範例程式碼

引用命名空間

using MongoDB.Bson;using MongoDB.Driver;

 

定義資料庫名和地址字

 

 private string connStr = "mongodb://xx.93.232.xx:27017"; private string dbName = "xxxx"; private IMongoDatabase database;

 

獲得dataBase

 var client = new MongoClient(connStr);            if (client != null)            {                database = client.GetDatabase(dbName);                bucket = new GridFSBucket(database); //這個是初始化gridFs儲存的            }

建立文檔集合

  private void CheckAddCreateCollection(string collectionName)        {            var collectionList = database.ListCollections().ToList();            var collectionNames = new List<string>();            //獲得所有集合的名稱            collectionList.ForEach(x => { collectionNames.Add(x["name"].AsString); });            //如果沒有這個集合就建立一個 (相當於建立一個表)            if (!collectionNames.Contains(collectionName))            {                database.CreateCollection(collectionName);            }        }

寫一個關於圖片資訊的類,這裡就用帳戶圖片來表示了

 public class UserAvatar    {        public  int AvatarId { get; set; }        public byte[] Avatar { get; set; }    }

 

如果你感到疑惑為什麼要建立一個類呢,因為mongon的任何crud操作都需要一個

IMongoCollection<TDocument>

的類型來進行操作。可以理解成ef中DbSet<xxxx>

擷取前面建立好的集合

  private IMongoCollection<UserAvatar> GetUserCollection(string name)        {            return database.GetCollection<UserAvatar>(name);  //傳入集合的名字        }

讀取圖片的位元組流

  var bytes = File.ReadAllBytes(@"C:\Users\哈哈哈\Desktop\test.jpg");

向mogoDb插入一條資料

 private  async  Task< bool> AddAvater(UserAvatar avatar, IMongoCollection<UserAvatar> userAvatar)        {           await  userAvatar.InsertOneAsync(avatar); //插入一條資料
//一下代碼是判斷了是否插入成功。 var result = userAvatar.AsQueryable().Where(x => x.AvatarId == avatar.AvatarId).Select(x => new UserAvatar { Avatar = x.Avatar, AvatarId = x.AvatarId }).ToList(); if (result.Count > 0) { this.textBox1.Text = result[0].AvatarId.ToString(); return true; } return false; }

讓我們到robo裡面看看是否插入成功了。

可以看到有資料了

從MogoDb取出一條資料

 private   Task<UserAvatar> GetUserAvatar(int avatarId,string collectionName)        {            var task = Task.Run(() =>            {                var userAvatar = GetUserCollection(collectionName);                var result = userAvatar.AsQueryable().Where(x => x.AvatarId == avatarId).Select(x => new UserAvatar { Avatar = x.Avatar, AvatarId = x.AvatarId }).ToList();                if (result.Count > 0)                {                    return result[0];                }                return null;            });            return task;        }

為什麼上面的代碼不在where後面直接toList呢?

答:MongoDb在文檔裡面會自動添加一個_id的欄位,這個時候反序列話,就不會成功了,報異常id不匹配。

讓我們來看下效果

顯示圖片的代碼

 private void ShowImage(byte[] imageBytes)        {            pictureBox1.Image = null;            MemoryStream memoryStream = new MemoryStream(imageBytes);            Image image = Image.FromStream(memoryStream);            Bitmap bitMap = new Bitmap(image, new Size(pictureBox1.Width, pictureBox1.Height));            pictureBox1.Image = bitMap;        }

 

看看資料庫圖片ID為95的在不在。

2:grifFs隱藏檔。按照Mongodb最新的文檔來說,基本上百度到一些C#使用gridFs來隱藏檔的文章已經沒有用用了。

根據Mongon文檔的介紹,GirdF是用來儲存大於16m的檔案。

GridFS是一種儲存大於最大文檔大小(目前為16MB)的二進位資訊的方法。當您將檔案上傳到GridFS時,檔案會分成多個塊並上傳各個塊。從GridFS下載檔案時,將從塊中重新組合原始內容。

初始化

 

 private GridFSBucket bucket;  bucket = new GridFSBucket(database);

 

 

根據官方文檔說明,GridFS檔案使用兩個集合儲存在資料庫中,通常稱為“fs.files”和“fs.chunks”。上傳到GridFS的每個檔案在“fs.files”集合中都有一個文檔,其中包含有關該檔案的資訊以及“fs.chunks”集合中用於隱藏檔內容的必要數量的塊。

GridFS“bucket”是“fs.files”和“fs.chunks”集合的組合,它們共同代表可以儲存GridFS檔案的儲存桶。

GridFSBucket對象是表示一個GridFS的桶的根對象。

可以看來使用GirdFSBucket來管理所有的檔案。

上傳檔案非常的簡單

var id = bucket.UploadFromBytes("filename", source); //source位元組數組var id = await bucket.UploadFromBytesAsync("filename", source);

如果上傳成功我們就會在robo中可以看到在collection分組下面會出現

fs.chunks,和fs.files兩個集合

先看看fs.files裡面儲存了

其中objectId,就是上面上傳代碼傳回值,toString之後的結果,

下載檔案 通過id來下載

  public  Task<byte[]> DownLoadFileFromGirdFs(ObjectId id)        {             return bucket.DownloadAsBytesAsync(id);        }

如果不知道Id怎麼辦?

就要先尋找檔案了用檔案名稱,上傳時間呀也可以來尋找

我是用檔案名稱來尋找的。如果你要問用那個objectId可以不可以尋找?

可以很清楚的告訴你,我沒有實驗成功,直接就會報異常,給我報Unable to determine the serialization information(無法確定的序列化資訊)

尋找代碼

 public ObjectId GetUploadFileId(string fileName)        {            var filter = Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, fileName);            //eq方法,就是等於,還有其他的方法,具體看Mongo的api文檔            var sort = Builders<GridFSFileInfo>.Sort.Descending(x => x.UploadDateTime);            //按上傳時間來倒敘一下            var options = new GridFSFindOptions            {                Limit = 1,                Sort = sort            };                      using (var cursor = bucket.Find(filter,options))            {                var fileInfo = cursor.ToList().FirstOrDefault();                if (fileInfo != null && fileInfo.Length > 0)                {                    return fileInfo.Id;                }                return new  ObjectId();            }        }

現在來結合下下載與尋找代碼來看下效果

  private async void button5_Click(object sender, EventArgs e)        {            var id = GetUploadFileId("yemobaiAvatar");            byte[] imageBytes= await  DownLoadFileFromGirdFs(id);            ShowImage(imageBytes);        }

結果

最後附上官方文檔地址   http://mongodb.github.io/mongo-csharp-driver/

 

 

 

 

 

 

C#使用MongoDb來隱藏檔

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.