上篇文章說了一下怎麼試用MongoDB來做replication,但是我是通過BSON Object來儲存檔案,這有個局限,就是如果檔案超過4m就會拋出超過最大檔案的異常。
根據官網介紹,BSON objects in MongoDB are limited to 4MB in size. http://www.mongodb.org/display/DOCS/GridFS
因此重新寫了那個操作類,使用GridFS來儲存檔案,代碼很簡單,但開始接觸弄了比較長時間,有一個問題一直解決不了,我希望自己產生一個Guid的 _id 而不是mongodb產生的_id,但是一直解決不了,希望哪個高手看到指點一下,謝謝!
這個是使用Mongodb官網提供的用戶端寫的:
using System;using System.Collections.Generic;using System.Text;using System.IO;using MongoDB.Driver;using MongoDB.Driver.Builders;using MongoDB.Bson;using MongoDB.Driver.GridFS;namespace FileUtility{ public class DocUtility { private string connStr = ""; public string ConnStr { get { if (string.IsNullOrEmpty(connStr)) { throw new ArgumentNullException("Connection string did not specify!"); } return connStr; } } public DocUtility() { connStr = System.Configuration.ConfigurationManager.AppSettings["FileDb"]; } public DocUtility(string connectionString) { this.connStr = connectionString; } /// <summary> /// add a document to mongodb /// </summary> /// <param name="content">document bytes array</param> /// <returns>the unique identity filename in mongodb</returns> public string AddDoc(byte[] content) { MongoServer server = MongoServer.Create(this.ConnStr); try { string filename = Guid.NewGuid().ToString(); server.Connect(); MongoDatabase db = server.GetDatabase("ecDocs"); MongoGridFS fs = new MongoGridFS(db, new MongoGridFSSettings() { Root="ecDocs" }); MongoGridFSFileInfo info = new MongoGridFSFileInfo(fs, filename); using (MongoGridFSStream gfs = info.Create()) { gfs.Write(content, 0, content.Length); } return filename; } catch (Exception ex) { throw ex; } finally { if (server != null) server.Disconnect(); } } /// <summary> /// delete doc from mongodb /// </summary> /// <param name="filename">the unique identity filename</param> public string DeleteDoc(string filename) { MongoServer server = MongoServer.Create(this.ConnStr); try { server.Connect(); MongoDatabase db = server.GetDatabase("ecDocs"); MongoGridFS fs = new MongoGridFS(db, new MongoGridFSSettings() { Root = "ecDocs" }); fs.Delete(filename); return filename; } catch (Exception ex) { throw ex; } finally { if (server != null) server.Disconnect(); } } /// <summary> /// get document bytes array from mongodb /// </summary> /// <param name="filename">unique filename</param> /// <returns>bytes array</returns> public byte[] GetDoc(string filename) { MongoServer server = MongoServer.Create(this.ConnStr); try { server.Connect(); MongoDatabase db = server.GetDatabase("ecDocs"); MongoGridFS fs = new MongoGridFS(db,new MongoGridFSSettings() { Root="ecDocs" }); byte[] bytes = null; using (MongoGridFSStream gfs = fs.Open(filename, FileMode.Open)) { bytes = new byte[gfs.Length]; gfs.Read(bytes, 0, bytes.Length); } return bytes; } catch (Exception ex) { throw ex; } finally { if (server != null) server.Disconnect(); } } }}
下面這個類是使用Samus的用戶端:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using MongoDB;using MongoDB.GridFS;namespace FileUtilitySamus{ public class DocUtility { private string connStr = ""; public string ConnStr { get { if (string.IsNullOrEmpty(connStr)) { throw new ArgumentNullException("Connection string did not specify!"); } return connStr; } } public DocUtility() { connStr = System.Configuration.ConfigurationManager.AppSettings["FileDb"]; } public DocUtility(string connectionString) { this.connStr = connectionString; } /// <summary> /// add a document to mongodb /// </summary> /// <param name="content">document bytes array</param> /// <returns>the unique identity filename in mongodb</returns> public string AddDoc(byte[] content) { using (Mongo mongo = new Mongo(this.ConnStr)) { try { string filename = Guid.NewGuid().ToString(); mongo.Connect(); IMongoDatabase db = mongo.GetDatabase("ecDoc"); GridFile fs = new GridFile(db, "ecDoc"); GridFileInfo info = new GridFileInfo(db, "ecDoc", filename); using (GridFileStream gfs = info.Create()) { gfs.Write(content, 0, content.Length); } return filename; } catch (Exception ex) { throw ex; } } } /// <summary> /// delete doc from mongodb /// </summary> /// <param name="filename">the unique identity filename</param> public void DeleteDoc(string filename) { using (Mongo mongo = new Mongo(this.ConnStr)) { try { mongo.Connect(); IMongoDatabase db = mongo.GetDatabase("ecDoc"); GridFile fs = new GridFile(db, "ecDoc"); fs.Delete(new Document("filename", filename)); } catch (Exception ex) { throw ex; } } } /// <summary> /// get document bytes array from mongodb /// </summary> /// <param name="filename">unique filename</param> /// <returns>bytes array</returns> public byte[] GetDoc(string filename) { using (Mongo mongo = new Mongo(this.ConnStr)) { try { mongo.Connect(); IMongoDatabase db = mongo.GetDatabase("ecDoc"); GridFile fs = new GridFile(db, "ecDoc"); GridFileStream gfs = fs.OpenRead(filename); byte[] bytes = new byte[gfs.Length]; gfs.Read(bytes, 0, bytes.Length); return bytes; } catch (Exception ex) { if (ex.GetType() == typeof(System.IO.DirectoryNotFoundException)) throw new System.IO.FileNotFoundException("File not found :" + filename); else throw ex; } } } }}
不知道兩個用戶端的效能相比如何?希望測試過的同學分享一下。