<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    備注學院

    LuLu

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      5 隨筆 :: 50 文章 :: 16 評論 :: 0 Trackbacks

    Berkeley DB是歷史悠久的嵌入式數(shù)據(jù)庫系統(tǒng),主要應用在UNIX/LINUX操作系統(tǒng)上。Berkeley DB的存儲的是key/value鍵值對,可以理解為硬盤上的超級hash表。其可以管理256TB數(shù)據(jù),而且能支撐幾千個并發(fā)訪問。目前Berkeley DB有C++版和Java版。所以,我們需要一個訪問的中間轉換,已經(jīng)有人發(fā)布了C#的API。可以從 Berkeley DB for .NET 上面找到,現(xiàn)在最新版是0.95版本,可以支持4.3和4.5版。本篇將以4.5版做實例。BerkeleyDB的版本可以在http://www.oracle.com/technology/products/berkeley-db/index.html下載,當前最新版本為4.7版。4.5 C++版的Berkeley DB可以在http://www.oracle.com/technology/software/products/berkeley-db/db/index.html這里下載。

     By Birdshover@ 博客園 http://www.cnblogs.com/birdshover/

    下載到Berkeley DB for .Net的API——libdb-dotnet_0_95.zip后,就可以開始使用了。首先在libdb-dotnet_0_95.zip解壓縮的bin目錄找到libdb_dotNET45.dll,這個就是4.5版本使用的dll。新建項目,引用這個dll。注意,自己編譯源碼可能會編譯不過,主要是因為里面一些委托和委托的參數(shù)可見性不一致造成的。把那些參數(shù)用到的class 或者struct都調成public即可。

     

    BerkeleyDB的數(shù)據(jù)庫操作需要借助DbBTree類。因此需要先得到DbBTree的實例,但是DbBTree類會對其它幾個類有依賴,必須依賴其它幾個類才能創(chuàng)建。

     下面代碼就是初始化得到DbBTree實例的一個過程。

           /// <summary>
    /// 數(shù)據(jù)庫目錄
    /// </summary>
    private string directory;
    /// <summary>
    /// 數(shù)據(jù)庫文件名
    /// </summary>
    private string dbName;

    private DbBTree btree;
    private Txn txn;
    private Db db;
    private Env env;
    /// <summary>
    /// 初始化
    /// </summary>
    private void Init()
    {
    env
    = new Env(EnvCreateFlags.None);
    Env.OpenFlags envFlags
    =
    Env.OpenFlags.Create
    |
    Env.OpenFlags.InitLock
    |
    Env.OpenFlags.InitLog
    |
    Env.OpenFlags.InitMPool
    |
    Env.OpenFlags.InitTxn
    |
    Env.OpenFlags.Recover;
    env.Open(directory, envFlags,
    0);
    txn
    = env.TxnBegin(null, Txn.BeginFlags.None);
    db
    = env.CreateDatabase(DbCreateFlags.None);
    btree
    = (DbBTree)db.Open(txn, dbName, null, DbType.BTree, Db.OpenFlags.Create, 0);
    }

     

    另外Berkeley DB數(shù)據(jù)庫的操作需要借助于序列化。

    
    
           /// <summary>
    /// 二進制序列化
    /// </summary>
    private BinaryFormatter formatter;
    /// <summary>
    /// 鍵內存流
    /// </summary>
    private MemoryStream keyStream;
    /// <summary>
    /// 內容內存流
    /// </summary>
    private MemoryStream dataStream;

    private void StreamInit()
    {
    formatter
    = new BinaryFormatter();
    keyStream
    = new MemoryStream();
    dataStream
    = new MemoryStream();
    }
    Berkeley DB是鍵值數(shù)據(jù)庫,因此定義一個獲取鍵接口:
        public interface IPut
    {
    string Key { get; }
    }
    
    
    一、數(shù)據(jù)庫的保存與更新
            public bool Set(IPut put)
    {
    Reset();

    keyStream.Position
    = 0;
    formatter.Serialize(keyStream, put.Key);
    DbEntry key
    = DbEntry.InOut(keyStream.GetBuffer(), 0, (int)keyStream.Position);
    dataStream.Position
    = 0;
    formatter.Serialize(dataStream, put);
    DbEntry data
    = DbEntry.InOut(dataStream.GetBuffer(), 0, (int)dataStream.Position);
    WriteStatus status
    = btree.Put(txn, ref key, ref data);
    switch (status)
    {
    case WriteStatus.Success:
    return true;
    case WriteStatus.NotFound:
    case WriteStatus.KeyExist:
    default:
    return false;
    }
    }
    上述代碼就可以保存鍵值。顯示對鍵值進行序列化,然后再保存。保存完有三個狀態(tài),可以一一處理。
    二、數(shù)據(jù)庫的刪除
    刪除最為簡單
            public bool Remove(IPut put)
    {
    keyStream.Position
    = 0;
    formatter.Serialize(keyStream, put.Key);
    DbEntry key
    = DbEntry.InOut(keyStream.GetBuffer(), 0, (int)keyStream.Position);
    DeleteStatus status
    = btree.Delete(txn, ref key);
    switch (status)
    {
    case DeleteStatus.NotFound:
    case DeleteStatus.Success:
    return true;
    case DeleteStatus.KeyEmpty:
    default:
    return false;
    }
    }
    
    
    
    
    三、關于添加和刪除
    添加和刪除并沒有真正得進行添加和刪除。必須執(zhí)行Commit操作:
            private bool iscomit = false;
    public void Commit()
    {
    txn.Commit(Txn.CommitMode.None);
    iscomit
    = true;
    }
    
    
    四、尋找鍵
    用鍵查詢值,和hash表一樣使用。
            public bool Get(ref IPut put)
    {
    keyStream.Position
    = 0;
    formatter.Serialize(keyStream, put.Key);
    DbEntry key
    = DbEntry.InOut(keyStream.GetBuffer(), 0, (int)keyStream.Position);
    dataStream.SetLength(dataStream.Capacity);
    DbEntry data
    = DbEntry.Out(dataStream.GetBuffer());

    while (true)
    {
    ReadStatus status
    = btree.Get(txn, ref key, ref data, DbFile.ReadFlags.None);

    switch (status)
    {
    case ReadStatus.Success:
    dataStream.Position
    = 0;
    dataStream.SetLength(data.Size);
    put
    = (IPut)formatter.Deserialize(dataStream);
    return true;
    case ReadStatus.BufferSmall: //擴容
    if (key.Buffer.Length < key.Size)
    {
    keyStream.SetLength(key.Size);
    key
    = DbEntry.Out(keyStream.GetBuffer());
    }
    if (data.Buffer.Length < data.Size)
    {
    dataStream.SetLength(data.Size);
    data
    = DbEntry.Out(dataStream.GetBuffer());
    }
    continue;
    case ReadStatus.NotFound:
    case ReadStatus.KeyEmpty:
    default:
    return false;
    }
    }
    }
    
    
    五、遍歷
    public List<IPut> Find()
    {
    List
    <IPut> custList = new List<IPut>();
    using (DbBTreeCursor cursor = btree.OpenCursor(txn, DbFileCursor.CreateFlags.None))
    {
    IPut cust
    = null;
    while (GetNextRecord(cursor, ref cust))
    custList.Add(cust);
    }
    return custList;
    }

    private bool GetNextRecord(DbBTreeCursor cursor, ref IPut cust)
    {
    ReadStatus status;
    keyStream.SetLength(keyStream.Capacity);
    dataStream.SetLength(dataStream.Capacity);
    DbEntry key
    = DbEntry.Out(keyStream.GetBuffer());
    DbEntry data
    = DbEntry.Out(dataStream.GetBuffer());
    do
    {
    status
    = cursor.Get(ref key, ref data, DbFileCursor.GetMode.Next, DbFileCursor.ReadFlags.None);
    switch (status)
    {
    case ReadStatus.NotFound: return false;
    case ReadStatus.KeyEmpty: continue; // skip deleted records
    case ReadStatus.BufferSmall:
    if (key.Buffer.Length < key.Size)
    {
    keyStream.SetLength(key.Size);
    key
    = DbEntry.Out(keyStream.GetBuffer());
    }
    if (data.Buffer.Length < data.Size)
    {
    dataStream.SetLength(data.Size);
    data
    = DbEntry.Out(dataStream.GetBuffer());
    }
    continue;
    case ReadStatus.Success:
    dataStream.Position
    = 0;
    dataStream.SetLength(data.Size);
    cust
    = (IPut)formatter.Deserialize(dataStream);
    return true;
    default:
    return false;
    }
    }
    while (true);
    }
    
    
    六、完整操作封裝

    public interface IPut
    {
    string Key { get; }
    }

    public class BDBManager : IDisposable
    {
    /// <summary>
    /// 數(shù)據(jù)庫目錄
    /// </summary>
    private string directory;
    /// <summary>
    /// 數(shù)據(jù)庫文件名
    /// </summary>
    private string dbName;

    private DbBTree btree;
    private Txn txn;
    private Db db;
    private Env env;

    /// <summary>
    /// 二進制序列化
    /// </summary>
    private BinaryFormatter formatter;
    /// <summary>
    /// 鍵內存流
    /// </summary>
    private MemoryStream keyStream;
    /// <summary>
    /// 內容內存流
    /// </summary>
    private MemoryStream dataStream;


    public BDBManager(string directory, string dbName)
    {
    this.directory = directory;
    this.dbName = dbName;

    Init();
    StreamInit();
    }

    public bool Set(IPut put)
    {
    Reset();

    keyStream.Position
    = 0;
    formatter.Serialize(keyStream, put.Key);
    DbEntry key
    = DbEntry.InOut(keyStream.GetBuffer(), 0, (int)keyStream.Position);
    dataStream.Position
    = 0;
    formatter.Serialize(dataStream, put);
    DbEntry data
    = DbEntry.InOut(dataStream.GetBuffer(), 0, (int)dataStream.Position);
    WriteStatus status
    = btree.Put(txn, ref key, ref data);
    switch (status)
    {
    case WriteStatus.Success:
    return true;
    case WriteStatus.NotFound:
    case WriteStatus.KeyExist:
    default:
    return false;
    }
    }

    private bool iscomit = false;
    public void Commit()
    {
    txn.Commit(Txn.CommitMode.None);
    iscomit
    = true;
    }

    public List<IPut> Find()
    {
    List
    <IPut> custList = new List<IPut>();
    using (DbBTreeCursor cursor = btree.OpenCursor(txn, DbFileCursor.CreateFlags.None))
    {
    IPut cust
    = null;
    while (GetNextRecord(cursor, ref cust))
    custList.Add(cust);
    }
    return custList;
    }

    public bool Get(ref IPut put)
    {
    keyStream.Position
    = 0;
    formatter.Serialize(keyStream, put.Key);
    DbEntry key
    = DbEntry.InOut(keyStream.GetBuffer(), 0, (int)keyStream.Position);
    dataStream.SetLength(dataStream.Capacity);
    DbEntry data
    = DbEntry.Out(dataStream.GetBuffer());

    while (true)
    {
    ReadStatus status
    = btree.Get(txn, ref key, ref data, DbFile.ReadFlags.None);

    switch (status)
    {
    case ReadStatus.Success:
    dataStream.Position
    = 0;
    dataStream.SetLength(data.Size);
    put
    = (IPut)formatter.Deserialize(dataStream);
    return true;
    case ReadStatus.BufferSmall: //擴容
    if (key.Buffer.Length < key.Size)
    {
    keyStream.SetLength(key.Size);
    key
    = DbEntry.Out(keyStream.GetBuffer());
    }
    if (data.Buffer.Length < data.Size)
    {
    dataStream.SetLength(data.Size);
    data
    = DbEntry.Out(dataStream.GetBuffer());
    }
    continue;
    case ReadStatus.NotFound:
    case ReadStatus.KeyEmpty:
    default:
    return false;
    }
    }
    }

    public bool Remove(IPut put)
    {
    Reset();

    keyStream.Position
    = 0;
    formatter.Serialize(keyStream, put.Key);
    DbEntry key
    = DbEntry.InOut(keyStream.GetBuffer(), 0, (int)keyStream.Position);
    DeleteStatus status
    = btree.Delete(txn, ref key);
    switch (status)
    {
    case DeleteStatus.NotFound:
    case DeleteStatus.Success:
    return true;
    case DeleteStatus.KeyEmpty:
    default:
    return false;
    }
    }

    public void Dispose()
    {
    if (!iscomit)
    Commit();
    db.Close();
    db.Close();
    }

    private void Reset()
    {
    iscomit
    = false;
    }

    private void Init()
    {
    env
    = new Env(EnvCreateFlags.None);
    Env.OpenFlags envFlags
    =
    Env.OpenFlags.Create
    |
    Env.OpenFlags.InitLock
    |
    Env.OpenFlags.InitLog
    |
    Env.OpenFlags.InitMPool
    |
    Env.OpenFlags.InitTxn
    |
    Env.OpenFlags.Recover;
    env.Open(directory, envFlags,
    0);
    txn
    = env.TxnBegin(null, Txn.BeginFlags.None);
    db
    = env.CreateDatabase(DbCreateFlags.None);
    btree
    = (DbBTree)db.Open(txn, dbName, null, DbType.BTree, Db.OpenFlags.Create, 0);
    }

    private void StreamInit()
    {
    formatter
    = new BinaryFormatter();
    keyStream
    = new MemoryStream();
    dataStream
    = new MemoryStream();
    }

    private bool GetNextRecord(DbBTreeCursor cursor, ref IPut cust)
    {
    ReadStatus status;
    keyStream.SetLength(keyStream.Capacity);
    dataStream.SetLength(dataStream.Capacity);
    DbEntry key
    = DbEntry.Out(keyStream.GetBuffer());
    DbEntry data
    = DbEntry.Out(dataStream.GetBuffer());
    do
    {
    status
    = cursor.Get(ref key, ref data, DbFileCursor.GetMode.Next, DbFileCursor.ReadFlags.None);
    switch (status)
    {
    case ReadStatus.NotFound: return false;
    case ReadStatus.KeyEmpty: continue; // skip deleted records
    case ReadStatus.BufferSmall:
    if (key.Buffer.Length < key.Size)
    {
    keyStream.SetLength(key.Size);
    key
    = DbEntry.Out(keyStream.GetBuffer());
    }
    if (data.Buffer.Length < data.Size)
    {
    dataStream.SetLength(data.Size);
    data
    = DbEntry.Out(dataStream.GetBuffer());
    }
    continue;
    case ReadStatus.Success:
    dataStream.Position
    = 0;
    dataStream.SetLength(data.Size);
    cust
    = (IPut)formatter.Deserialize(dataStream);
    return true;
    default:
    return false;
    }
    }
    while (true);
    }
    }
    調用方法:
    首先要有一個寫入的實體類,必須可以序列化,并且實現(xiàn)IPut接口:
            [Serializable()]
    class Item : IPut
    {
    public string Name { get; set; }
    public string Text { get; set; }
    public int ID { get; set; }

    public override string ToString()
    {
    return string.Format("ID:{0} Key:{1}", ID, Name);
    }

    public string Key
    {
    get { return Name; }
    }
    }
    操作:
               using (BDBManager manager = new BDBManager("db", "db.dat"))
    {
    bool success = manager.Set(new Item() { ID = 1000, Name = "Test",Text = "213" });
    Console.WriteLine(
    string.Format("set is {0}", success));
    }

    using (BDBManager manager = new BDBManager("db", "db.dat"))
    {
    IPut put
    = new Item() { Name = "Test" };
    bool success = manager.Get(ref put);
    Console.WriteLine(
    string.Format("read is {0},item : {1}", success, put.ToString()));
    }

    using (BDBManager manager = new BDBManager("db", "db.dat"))
    {
    IPut put
    = new Item() { Name = "Test" };
    bool success = manager.Remove(put);
    Console.WriteLine(
    string.Format("remove is {0},item : {1}", success, put.ToString()));
    }

    using (BDBManager manager = new BDBManager("db", "db.dat"))
    {
    List
    <IPut> list = manager.Find();
    foreach (var item in list)
    {
    Console.WriteLine(item.ToString());
    }
    }
    Console.WriteLine(
    "end");
    Console.ReadKey();
    posted on 2008-11-13 10:37 smildlzj 閱讀(344) 評論(0)  編輯  收藏 所屬分類: 數(shù)據(jù)庫 、C#
    主站蜘蛛池模板: 免费黄色小视频网站| 亚洲电影免费观看| 免费A级毛片在线播放不收费| 激情五月亚洲色图| 又粗又大又黑又长的免费视频 | 又黄又爽一线毛片免费观看 | 美女裸体无遮挡免费视频网站| 国内一级一级毛片a免费| 亚洲一区二区三区高清在线观看| 无码人妻精品中文字幕免费东京热| 久久丫精品国产亚洲av| 84pao国产成视频免费播放| 亚洲va乱码一区二区三区| 欧亚精品一区三区免费| 亚洲国产精品久久久久秋霞小| 精品久久久久久久免费人妻| 国产成人综合亚洲一区| 国产成人精品曰本亚洲79ren| 久久国产精品免费一区| 亚洲国产精品免费视频| 一本岛高清v不卡免费一三区| 亚洲欧洲无码一区二区三区| 国产一级高清视频免费看| 国产免费福利体检区久久| 亚洲av无码国产精品色午夜字幕| 57pao国产成视频免费播放| 久久精品国产亚洲av麻豆蜜芽 | 久久综合亚洲色hezyo| 亚洲一级特黄大片在线观看| 午夜无码A级毛片免费视频| 亚洲国产视频久久| www.亚洲精品.com| 亚洲免费视频在线观看| 亚洲日本一线产区和二线| 国产亚洲午夜高清国产拍精品 | 午夜不卡AV免费| 亚洲一区二区中文| 国产在线19禁免费观看| 成在人线av无码免费高潮喷水 | 红杏亚洲影院一区二区三区| 久久久精品2019免费观看|