GroupFileContainer.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. using HslCommunication.Core;
  2. using HslCommunication.LogNet;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Text;
  8. namespace HslCommunication.Enthernet
  9. {
  10. /// <summary>
  11. /// 文件集容器,绑定一个文件夹的文件信息组
  12. /// </summary>
  13. public class GroupFileContainer
  14. {
  15. #region Constructor
  16. /// <summary>
  17. /// 实例化一个新的数据管理容器
  18. /// </summary>
  19. /// <param name="logNet">日志记录对象,可以为空</param>
  20. /// <param name="path"></param>
  21. public GroupFileContainer( ILogNet logNet, string path )
  22. {
  23. LogNet = logNet;
  24. GroupFileContainerLoadByPath( path );
  25. }
  26. #endregion
  27. #region Public Members
  28. /// <summary>
  29. /// 包含所有文件列表信息的json文本缓存
  30. /// </summary>
  31. public string JsonArrayContent
  32. {
  33. get { return m_JsonArrayContent; }
  34. }
  35. /// <summary>
  36. /// 获取文件的数量
  37. /// </summary>
  38. public int FileCount
  39. {
  40. get { return m_filesCount; }
  41. }
  42. #endregion
  43. #region Event Handle
  44. private void OnFileCountChanged( )
  45. {
  46. FileCountChanged?.Invoke( m_filesCount );
  47. }
  48. /// <summary>
  49. /// 当文件数量发生变化的时候触发的事件
  50. /// </summary>
  51. public event Action<int> FileCountChanged;
  52. #endregion
  53. #region Upload Download Delete
  54. /// <summary>
  55. /// 下载文件时调用
  56. /// </summary>
  57. /// <param name="fileName"></param>
  58. /// <returns></returns>
  59. public string GetCurrentFileMappingName( string fileName )
  60. {
  61. string source = Guid.NewGuid( ).ToString( "N" );
  62. hybirdLock.Enter( );
  63. for (int i = 0; i < m_files.Count; i++)
  64. {
  65. if (m_files[i].FileName == fileName)
  66. {
  67. source = m_files[i].MappingName;
  68. m_files[i].DownloadTimes++;
  69. }
  70. }
  71. hybirdLock.Leave( );
  72. // 更新缓存
  73. coordinatorCacheJsonArray.StartOperaterInfomation( );
  74. return source;
  75. }
  76. /// <summary>
  77. /// 上传文件时掉用
  78. /// </summary>
  79. /// <param name="fileName">文件名,带后缀,不带任何的路径</param>
  80. /// <param name="fileSize">文件的大小</param>
  81. /// <param name="mappingName">文件映射名称</param>
  82. /// <param name="owner">文件的拥有者</param>
  83. /// <param name="description">文件的额外描述</param>
  84. /// <returns></returns>
  85. public string UpdateFileMappingName( string fileName, long fileSize, string mappingName, string owner, string description )
  86. {
  87. string source = string.Empty;
  88. hybirdLock.Enter( );
  89. for (int i = 0; i < m_files.Count; i++)
  90. {
  91. if (m_files[i].FileName == fileName)
  92. {
  93. source = m_files[i].MappingName;
  94. m_files[i].MappingName = mappingName;
  95. m_files[i].Description = description;
  96. m_files[i].FileSize = fileSize;
  97. m_files[i].Owner = owner;
  98. m_files[i].UploadTime = DateTime.Now;
  99. break;
  100. }
  101. }
  102. if (string.IsNullOrEmpty( source ))
  103. {
  104. // 文件不存在
  105. m_files.Add( new GroupFileItem( )
  106. {
  107. FileName = fileName,
  108. FileSize = fileSize,
  109. DownloadTimes = 0,
  110. Description = description,
  111. Owner = owner,
  112. MappingName = mappingName,
  113. UploadTime = DateTime.Now
  114. } );
  115. }
  116. hybirdLock.Leave( );
  117. // 更新缓存
  118. coordinatorCacheJsonArray.StartOperaterInfomation( );
  119. return source;
  120. }
  121. /// <summary>
  122. /// 删除一个文件信息
  123. /// </summary>
  124. /// <param name="fileName"></param>
  125. /// <returns></returns>
  126. public string DeleteFile( string fileName )
  127. {
  128. string source = string.Empty;
  129. hybirdLock.Enter( );
  130. for (int i = 0; i < m_files.Count; i++)
  131. {
  132. if (m_files[i].FileName == fileName)
  133. {
  134. source = m_files[i].MappingName;
  135. m_files.RemoveAt( i );
  136. break;
  137. }
  138. }
  139. hybirdLock.Leave( );
  140. // 更新缓存
  141. coordinatorCacheJsonArray.StartOperaterInfomation( );
  142. return source;
  143. }
  144. #endregion
  145. #region Private Method
  146. /// <summary>
  147. /// 缓存JSON文本的方法,该机制使用乐观并发模型完成
  148. /// </summary>
  149. private void CacheJsonArrayContent( )
  150. {
  151. hybirdLock.Enter( );
  152. m_filesCount = m_files.Count;
  153. m_JsonArrayContent = Newtonsoft.Json.Linq.JArray.FromObject( m_files ).ToString( );
  154. // 保存文件
  155. using (StreamWriter sw = new StreamWriter( m_filePath + FileListResources, false, Encoding.UTF8 ))
  156. {
  157. sw.Write( m_JsonArrayContent );
  158. }
  159. hybirdLock.Leave( );
  160. // 通知更新
  161. OnFileCountChanged( );
  162. }
  163. /// <summary>
  164. /// 从目录进行加载数据,必须实例化的时候加载,加载失败会导致系统异常,旧的文件丢失
  165. /// </summary>
  166. /// <param name="path"></param>
  167. private void GroupFileContainerLoadByPath( string path )
  168. {
  169. m_filePath = path;
  170. if (!Directory.Exists( m_filePath ))
  171. {
  172. Directory.CreateDirectory( m_filePath );
  173. }
  174. if (File.Exists( m_filePath + FileListResources ))
  175. {
  176. try
  177. {
  178. using (StreamReader sr = new StreamReader( m_filePath + FileListResources, Encoding.UTF8 ))
  179. {
  180. m_files = Newtonsoft.Json.Linq.JArray.Parse( sr.ReadToEnd( ) ).ToObject<List<GroupFileItem>>( );
  181. }
  182. }
  183. catch (Exception ex)
  184. {
  185. LogNet?.WriteException( "GroupFileContainer", "Load files txt failed,", ex );
  186. }
  187. }
  188. if (m_files == null)
  189. {
  190. m_files = new List<GroupFileItem>( );
  191. }
  192. coordinatorCacheJsonArray = new HslAsyncCoordinator( CacheJsonArrayContent );
  193. CacheJsonArrayContent( );
  194. }
  195. #endregion
  196. #region Private Members
  197. private const string FileListResources = "\\list.txt"; // 文件名
  198. private ILogNet LogNet; // 日志对象
  199. private string m_JsonArrayContent = "[]"; // 缓存数据
  200. private int m_filesCount = 0; // 文件数量
  201. private SimpleHybirdLock hybirdLock = new SimpleHybirdLock( ); // 简单混合锁
  202. private HslAsyncCoordinator coordinatorCacheJsonArray; // 乐观并发模型
  203. private List<GroupFileItem> m_files; // 文件队列
  204. private string m_filePath; // 文件路径
  205. #endregion
  206. }
  207. }