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/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did46009