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