好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

C#实现文件数据库

C#实现文件数据库

C#实现文件数据库

如果你需要一个简单的磁盘文件索引数据库,这篇文章可以帮助你。

文件数据库描述:

每个文档对象保存为一个独立文件,例如一篇博客。 文件内容序列化支持XML或JSON。 支持基本的CRUD操作。

文件数据库抽象类实现

View Code

  1     ///   <summary> 
   2     ///   文件数据库,这是一个抽象类。
    3     ///   </summary> 
   4     public   abstract   class   FileDatabase
    5     {
    6       #region  Fields
   7  
   8       ///   <summary> 
   9       ///   文件数据库操作锁
   10       ///   </summary> 
  11       protected   static   readonly   object  operationLock =  new   object  ();
   12       private   static  HashSet< char >  invalidFileNameChars;
   13  
  14       static   FileDatabase()
   15       {
   16        invalidFileNameChars =  new  HashSet< char >() {  '  \0  ' ,  '   ' ,  '  .  ' ,  '  $  ' ,  '  /  ' ,  '  \\  '   };
   17         foreach  ( var  c  in   Path.GetInvalidPathChars()) { invalidFileNameChars.Add(c); }
   18         foreach  ( var  c  in   Path.GetInvalidFileNameChars()) { invalidFileNameChars.Add(c); }
   19       }
   20  
  21       ///   <summary> 
  22       ///   文件数据库
   23       ///   </summary> 
  24       ///   <param name="directory">  数据库文件所在目录  </param> 
  25       protected  FileDatabase( string   directory)
   26       {
   27        Directory =  directory;
   28       }
   29  
  30       #endregion 
  31  
  32       #region  Properties
  33  
  34       ///   <summary> 
  35       ///   数据库文件所在目录
   36       ///   </summary> 
  37       public   virtual   string  Directory {  get ;  private   set  ; }
   38  
  39       ///   <summary> 
  40       ///   是否输出缩进
   41       ///   </summary> 
  42       public   virtual   bool  OutputIndent {  get ;  set  ; }
   43  
  44       ///   <summary> 
  45       ///   文件扩展名
   46       ///   </summary> 
  47       public   virtual   string  FileExtension {  get ;  set  ; }
   48  
  49       #endregion 
  50  
  51       #region  Public Methods
  52  
  53       ///   <summary> 
  54       ///   保存文档
   55       ///   </summary> 
  56       ///   <typeparam name="TDocument">  文档类型  </typeparam> 
  57       ///   <param name="document">  文档对象  </param> 
  58       ///   <returns>  文档ID  </returns> 
  59       public   virtual   string  Save<TDocument> (TDocument document)
   60       {
   61         return  Save<TDocument> (ObjectId.NewObjectId().ToString(), document);
   62       }
   63  
  64       ///   <summary> 
  65       ///   保存文档
   66       ///   </summary> 
  67       ///   <typeparam name="TDocument">  文档类型  </typeparam> 
  68       ///   <param name="id">  文档ID  </param> 
  69       ///   <param name="document">  文档对象  </param> 
  70       ///   <returns>  文档ID  </returns> 
  71       public   virtual   string  Save<TDocument>( string   id, TDocument document)
   72       {
   73         if  ( string  .IsNullOrEmpty(id))
   74           throw   new  ArgumentNullException( "  id  "  );
   75  
  76         if  (document ==  null  )
   77           throw   new  ArgumentNullException( "  document  "  );
   78  
  79        Delete<TDocument> (id);
   80  
  81         try 
  82         {
   83           string  fileName = GenerateFileFullPath<TDocument> (id);
   84           string  output =  Serialize(document);
   85  
  86           lock   (operationLock)
   87           {
   88            System.IO.FileInfo info =  new   System.IO.FileInfo(fileName);
   89             System.IO.Directory.CreateDirectory(info.Directory.FullName);
   90             System.IO.File.WriteAllText(fileName, output);
   91           }
   92         }
   93         catch   (Exception ex)
   94         {
   95           throw   new   FileDatabaseException(
   96             string  .Format(CultureInfo.InvariantCulture, 
   97             "  Save document failed with id [{0}].  "  , id), ex);
   98         }
   99  
 100         return   id;
  101       }
  102  
 103       ///   <summary> 
 104       ///   根据文档ID查找文档
  105       ///   </summary> 
 106       ///   <typeparam name="TDocument">  文档类型  </typeparam> 
 107       ///   <param name="id">  文档ID  </param> 
 108       ///   <returns>  文档对象  </returns> 
 109       public   virtual  TDocument FindOneById<TDocument>( string   id)
  110       {
  111         if  ( string  .IsNullOrEmpty(id))
  112           throw   new  ArgumentNullException( "  id  "  );
  113  
 114         try 
 115         {
  116           string  fileName = GenerateFileFullPath<TDocument> (id);
  117           if   (File.Exists(fileName))
  118           {
  119             string  fileData =  File.ReadAllText(fileName);
  120             return  Deserialize<TDocument> (fileData);
  121           }
  122  
 123           return   default  (TDocument);
  124         }
  125         catch   (Exception ex)
  126         {
  127           throw   new   FileDatabaseException(
  128             string  .Format(CultureInfo.InvariantCulture, 
  129             "  Find document by id [{0}] failed.  "  , id), ex);
  130         }
  131       }
  132  
 133       ///   <summary> 
 134       ///   查找指定类型的所有文档
  135       ///   </summary> 
 136       ///   <typeparam name="TDocument">  文档类型  </typeparam> 
 137       ///   <returns>  文档对象序列  </returns> 
 138       public   virtual  IEnumerable<TDocument> FindAll<TDocument> ()
  139       {
  140         try 
 141         {
  142           string [] files =  System.IO.Directory.GetFiles(
  143            GenerateFilePath<TDocument> (), 
  144             "  *.  "  +  FileExtension, 
  145             SearchOption.TopDirectoryOnly);
  146  
 147          List<TDocument> list =  new  List<TDocument> ();
  148           foreach  ( string  fileName  in   files)
  149           {
  150             string  fileData =  File.ReadAllText(fileName);
  151            TDocument document = Deserialize<TDocument> (fileData);
  152             if  (document !=  null  )
  153             {
  154               list.Add(document);
  155             }
  156           }
  157  
 158           return   list;
  159         }
  160         catch   (Exception ex)
  161         {
  162           throw   new   FileDatabaseException(
  163             "  Find all documents failed.  "  , ex);
  164         }
  165       }
  166  
 167       ///   <summary> 
 168       ///   根据指定文档ID删除文档
  169       ///   </summary> 
 170       ///   <typeparam name="TDocument">  文档类型  </typeparam> 
 171       ///   <param name="id">  文档ID  </param> 
 172       public   virtual   void  Delete<TDocument>( string   id)
  173       {
  174         if  ( string  .IsNullOrEmpty(id))
  175           throw   new  ArgumentNullException( "  id  "  );
  176  
 177         try 
 178         {
  179           string  fileName = GenerateFileFullPath<TDocument> (id);
  180           if   (File.Exists(fileName))
  181           {
  182             lock   (operationLock)
  183             {
  184               File.Delete(fileName);
  185             }
  186           }
  187         }
  188         catch   (Exception ex)
  189         {
  190           throw   new   FileDatabaseException(
  191             string  .Format(CultureInfo.InvariantCulture, 
  192             "  Delete document by id [{0}] failed.  "  , id), ex);
  193         }
  194       }
  195  
 196       ///   <summary> 
 197       ///   删除所有指定类型的文档
  198       ///   </summary> 
 199       ///   <typeparam name="TDocument">  文档类型  </typeparam> 
 200       public   virtual   void  DeleteAll<TDocument> ()
  201       {
  202         try 
 203         {
  204           string [] files =  System.IO.Directory.GetFiles(
  205            GenerateFilePath<TDocument>(),  "  *.  "  +  FileExtension, 
  206             SearchOption.TopDirectoryOnly);
  207  
 208           foreach  ( string  fileName  in   files)
  209           {
  210             lock   (operationLock)
  211             {
  212               File.Delete(fileName);
  213             }
  214           }
  215         }
  216         catch   (Exception ex)
  217         {
  218           throw   new   FileDatabaseException(
  219             "  Delete all documents failed.  "  , ex);
  220         }
  221       }
  222  
 223       ///   <summary> 
 224       ///   获取指定类型文档的数量
  225       ///   </summary> 
 226       ///   <typeparam name="TDocument">  文档类型  </typeparam> 
 227       ///   <returns>  文档的数量  </returns> 
 228       public   virtual   int  Count<TDocument> ()
  229       {
  230         try 
 231         {
  232           string [] files =  System.IO.Directory.GetFiles(
  233            GenerateFilePath<TDocument> (), 
  234             "  *.  "  +  FileExtension, SearchOption.TopDirectoryOnly);
  235           if  (files !=  null  )
  236           {
  237             return   files.Length;
  238           }
  239           else 
 240           {
  241             return   0  ;
  242           }
  243         }
  244         catch   (Exception ex)
  245         {
  246           throw   new   FileDatabaseException(
  247             "  Count all documents failed.  "  , ex);
  248         }
  249       }
  250  
 251       #endregion 
 252  
 253       #region  Protected Methods
 254  
 255       ///   <summary> 
 256       ///   生成文件全路径
  257       ///   </summary> 
 258       ///   <typeparam name="TDocument">  文档类型  </typeparam> 
 259       ///   <param name="id">  文档ID  </param> 
 260       ///   <returns>  文件路径  </returns> 
 261       protected   virtual   string  GenerateFileFullPath<TDocument>( string   id)
  262       {
  263         return  Path.Combine(GenerateFilePath<TDocument> (), 
  264          GenerateFileName<TDocument> (id));
  265       }
  266  
 267       ///   <summary> 
 268       ///   生成文件路径
  269       ///   </summary> 
 270       ///   <typeparam name="TDocument">  文档类型  </typeparam> 
 271       ///   <returns>  文件路径  </returns> 
 272       protected   virtual   string  GenerateFilePath<TDocument> ()
  273       {
  274         return  Path.Combine( this .Directory,  typeof  (TDocument).Name);
  275       }
  276  
 277       ///   <summary> 
 278       ///   生成文件名
  279       ///   </summary> 
 280       ///   <typeparam name="TDocument">  文档类型  </typeparam> 
 281       ///   <param name="id">  文档ID  </param> 
 282       ///   <returns>  文件名  </returns> 
 283       protected   virtual   string  GenerateFileName<TDocument>( string   id)
  284       {
  285         if  ( string  .IsNullOrEmpty(id))
  286           throw   new  ArgumentNullException( "  id  "  );
  287  
 288         foreach  ( char  c  in   id)
  289         {
  290           if   (invalidFileNameChars.Contains(c))
  291           {
  292             throw   new   FileDatabaseException(
  293               string  .Format(CultureInfo.InvariantCulture, 
  294               "  The character '{0}' is not a valid file name identifier.  "  , c));
  295           }
  296         }
  297  
 298         return   string .Format(CultureInfo.InvariantCulture,  "  {0}.{1}  "  , id, FileExtension);
  299       }
  300  
 301       ///   <summary> 
 302       ///   将指定的文档对象序列化至字符串
  303       ///   </summary> 
 304       ///   <param name="value">  指定的文档对象  </param> 
 305       ///   <returns>  文档对象序列化后的字符串  </returns> 
 306       protected   abstract   string  Serialize( object   value);
  307  
 308       ///   <summary> 
 309       ///   将字符串反序列化成文档对象
  310       ///   </summary> 
 311       ///   <typeparam name="TDocument">  文档类型  </typeparam> 
 312       ///   <param name="data">  字符串  </param> 
 313       ///   <returns>  文档对象  </returns> 
 314       protected   abstract  TDocument Deserialize<TDocument>( string   data);
  315  
 316       #endregion 
 317    }

XML文件数据库实现

  1     ///   <summary> 
  2     ///   XML文件数据库
   3     ///   </summary> 
  4     public   class   XmlDatabase : FileDatabase
   5     {
   6       ///   <summary> 
  7       ///   XML文件数据库
   8       ///   </summary> 
  9       ///   <param name="directory">  数据库文件所在目录  </param> 
 10       public  XmlDatabase( string   directory)
  11        :  base  (directory)
  12       {
  13        FileExtension =  @"  xml  "  ;
  14       }
  15  
 16       ///   <summary> 
 17       ///   将指定的文档对象序列化至字符串
  18       ///   </summary> 
 19       ///   <param name="value">  指定的文档对象  </param> 
 20       ///   <returns> 
 21       ///   文档对象序列化后的字符串
  22       ///   </returns> 
 23       protected   override   string  Serialize( object   value)
  24       {
  25         if  (value ==  null  )
  26           throw   new  ArgumentNullException( "  value  "  );
  27  
 28         using  (StringWriterWithEncoding sw =  new   StringWriterWithEncoding(Encoding.UTF8))
  29         {
  30          XmlSerializer serializer =  new   XmlSerializer(value.GetType());
  31           serializer.Serialize(sw, value);
  32           return   sw.ToString();
  33         }
  34       }
  35  
 36       ///   <summary> 
 37       ///   将字符串反序列化成文档对象
  38       ///   </summary> 
 39       ///   <typeparam name="TDocument">  文档类型  </typeparam> 
 40       ///   <param name="data">  字符串  </param> 
 41       ///   <returns> 
 42       ///   文档对象
  43       ///   </returns> 
 44       protected   override  TDocument Deserialize<TDocument>( string   data)
  45       {
  46         if  ( string  .IsNullOrEmpty(data))
  47           throw   new  ArgumentNullException( "  data  "  );
  48  
 49         using  (StringReader sr =  new   StringReader(data))
  50         {
  51          XmlSerializer serializer =  new  XmlSerializer( typeof  (TDocument));
  52           return   (TDocument)serializer.Deserialize(sr);
  53         }
  54       }
  55    }

JSON文件数据库实现

  1     ///   <summary> 
  2     ///   JSON文件数据库
   3     ///   </summary> 
  4     public   class   JsonDatabase : FileDatabase
   5     {
   6       ///   <summary> 
  7       ///   JSON文件数据库
   8       ///   </summary> 
  9       ///   <param name="directory">  数据库文件所在目录  </param> 
 10       public  JsonDatabase( string   directory)
  11        :  base  (directory)
  12       {
  13        FileExtension =  @"  json  "  ;
  14       }
  15  
 16       ///   <summary> 
 17       ///   将指定的文档对象序列化至字符串
  18       ///   </summary> 
 19       ///   <param name="value">  指定的文档对象  </param> 
 20       ///   <returns> 
 21       ///   文档对象序列化后的字符串
  22       ///   </returns> 
 23       protected   override   string  Serialize( object   value)
  24       {
  25         if  (value ==  null  )
  26           throw   new  ArgumentNullException( "  value  "  );
  27  
 28         return   JsonConvert.SerializeObject(value, OutputIndent);
  29       }
  30  
 31       ///   <summary> 
 32       ///   将字符串反序列化成文档对象
  33       ///   </summary> 
 34       ///   <typeparam name="TDocument">  文档类型  </typeparam> 
 35       ///   <param name="data">  字符串  </param> 
 36       ///   <returns> 
 37       ///   文档对象
  38       ///   </returns> 
 39       protected   override  TDocument Deserialize<TDocument>( string   data)
  40       {
  41         if  ( string  .IsNullOrEmpty(data))
  42           throw   new  ArgumentNullException( "  data  "  );
  43  
 44         return  JsonConvert.DeserializeObject<TDocument> (data);
  45       }
  46    }

Test Double

  1     [Serializable]
   2     public   class   Cat
   3     {
   4       public   Cat()
   5       {
   6        Id =  ObjectId.NewObjectId().ToString();
   7       }
   8  
  9       public  Cat( string   id)
  10       {
  11        Id =  id;
  12       }
  13  
 14       public   string  Name {  get ;  set  ; }
  15       public   int  Legs {  get ;  set  ; }
  16  
 17       public   string  Id {  get ;  set  ; }
  18  
 19       public   override   string   ToString()
  20       {
  21         return   string .Format( "  DocumentId={0}, Name={1}, Legs={2}  "  , Id, Name, Legs);
  22       }
  23    }

使用举例

  1     class   Program
   2     {
   3       static   void  Main( string  [] args)
   4       {
   5         TestJsonDatabase();
   6         TestXmlDatabase();
   7  
  8         Console.ReadKey();
   9       }
  10  
 11       private   static   void   TestJsonDatabase()
  12       {
  13        JsonDatabase db =  new  JsonDatabase( @"  C:\tmp  "  );
  14        db.OutputIndent =  true  ;
  15  
 16        Cat origin =  new  Cat() { Name =  "  Garfield  " , Legs =  4   };
  17        db.Save<Cat> (origin);
  18  
 19        db.Save<Cat> (origin.Id, origin);
  20        db.Delete<Cat> (origin.Id);
  21       }
  22  
 23       private   static   void   TestXmlDatabase()
  24       {
  25        XmlDatabase db =  new  XmlDatabase( @"  C:\tmp  "  );
  26        db.OutputIndent =  true  ;
  27  
 28        Cat origin =  new  Cat() { Name =  "  Garfield  " , Legs =  4   };
  29        db.Save<Cat> (origin);
  30  
 31        db.Save<Cat> (origin.Id, origin);
  32        db.Delete<Cat> (origin.Id);
  33       }
  34    }

 

 

 

 

标签:  C# ,  Database

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于C#实现文件数据库的详细内容...

  阅读:37次