分享

C#实现文件数据库

 昵称10504424 2014-01-07

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

文件数据库描述:

文件数据库抽象类实现

复制代码
  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文件数据库实现

JSON文件数据库实现

Test Double

使用举例

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约