using HslCommunication.Core; using HslCommunication.LogNet; using System; using System.Collections.Generic; using System.IO; using System.Text; namespace HslCommunication.Enthernet { /// <summary> /// 文件集容器,绑定一个文件夹的文件信息组 /// </summary> public class GroupFileContainer { #region Constructor /// <summary> /// 实例化一个新的数据管理容器 /// </summary> /// <param name="logNet">日志记录对象,可以为空</param> /// <param name="path">文件的路径</param> public GroupFileContainer(ILogNet logNet, string path) { LogNet = logNet; GroupFileContainerLoadByPath(path); } #endregion #region Public Members /// <summary> /// 包含所有文件列表信息的json文本缓存 /// </summary> public string JsonArrayContent { get { return m_JsonArrayContent; } } /// <summary> /// 获取文件的数量 /// </summary> public int FileCount { get { return m_filesCount; } } #endregion #region Event Handle private void OnFileCountChanged() { FileCountChanged?.Invoke(m_filesCount); } /// <summary> /// 当文件数量发生变化的时候触发的事件 /// </summary> public event Action<int> FileCountChanged; #endregion #region Upload Download Delete /// <summary> /// 下载文件时调用 /// </summary> /// <param name="fileName">文件的实际名称</param> /// <returns>文件名映射过去的实际的文件名字</returns> public string GetCurrentFileMappingName(string fileName) { string source = Guid.NewGuid().ToString("N"); hybirdLock.Enter(); for (int i = 0; i < m_files.Count; i++) { if (m_files[i].FileName == fileName) { source = m_files[i].MappingName; m_files[i].DownloadTimes++; } } hybirdLock.Leave(); // 更新缓存 coordinatorCacheJsonArray.StartOperaterInfomation(); return source; } /// <summary> /// 上传文件时掉用 /// </summary> /// <param name="fileName">文件名,带后缀,不带任何的路径</param> /// <param name="fileSize">文件的大小</param> /// <param name="mappingName">文件映射名称</param> /// <param name="owner">文件的拥有者</param> /// <param name="description">文件的额外描述</param> /// <returns>映射的文件名称</returns> public string UpdateFileMappingName(string fileName, long fileSize, string mappingName, string owner, string description) { string source = string.Empty; hybirdLock.Enter(); for (int i = 0; i < m_files.Count; i++) { if (m_files[i].FileName == fileName) { source = m_files[i].MappingName; m_files[i].MappingName = mappingName; m_files[i].Description = description; m_files[i].FileSize = fileSize; m_files[i].Owner = owner; m_files[i].UploadTime = DateTime.Now; break; } } if (string.IsNullOrEmpty(source)) { // 文件不存在 m_files.Add(new GroupFileItem() { FileName = fileName, FileSize = fileSize, DownloadTimes = 0, Description = description, Owner = owner, MappingName = mappingName, UploadTime = DateTime.Now }); } hybirdLock.Leave(); // 更新缓存 coordinatorCacheJsonArray.StartOperaterInfomation(); return source; } /// <summary> /// 删除一个文件信息 /// </summary> /// <param name="fileName">实际的文件名称</param> /// <returns>映射之后的文件名</returns> public string DeleteFile(string fileName) { string source = string.Empty; hybirdLock.Enter(); for (int i = 0; i < m_files.Count; i++) { if (m_files[i].FileName == fileName) { source = m_files[i].MappingName; m_files.RemoveAt(i); break; } } hybirdLock.Leave(); // 更新缓存 coordinatorCacheJsonArray.StartOperaterInfomation(); return source; } #endregion #region Private Method /// <summary> /// 缓存JSON文本的方法,该机制使用乐观并发模型完成 /// </summary> private void CacheJsonArrayContent() { hybirdLock.Enter(); m_filesCount = m_files.Count; m_JsonArrayContent = Newtonsoft.Json.Linq.JArray.FromObject(m_files).ToString(); // 保存文件 using (StreamWriter sw = new StreamWriter(m_filePath + FileListResources, false, Encoding.UTF8)) { sw.Write(m_JsonArrayContent); } hybirdLock.Leave(); // 通知更新 OnFileCountChanged(); } /// <summary> /// 从目录进行加载数据,必须实例化的时候加载,加载失败会导致系统异常,旧的文件丢失 /// </summary> /// <param name="path"></param> private void GroupFileContainerLoadByPath(string path) { m_filePath = path; if (!Directory.Exists(m_filePath)) { Directory.CreateDirectory(m_filePath); } if (File.Exists(m_filePath + FileListResources)) { try { using (StreamReader sr = new StreamReader(m_filePath + FileListResources, Encoding.UTF8)) { m_files = Newtonsoft.Json.Linq.JArray.Parse(sr.ReadToEnd()).ToObject<List<GroupFileItem>>(); } } catch (Exception ex) { LogNet?.WriteException("GroupFileContainer", "Load files txt failed,", ex); } } if (m_files == null) { m_files = new List<GroupFileItem>(); } coordinatorCacheJsonArray = new HslAsyncCoordinator(CacheJsonArrayContent); CacheJsonArrayContent(); } #endregion #region Private Members private const string FileListResources = "\\list.txt"; // 文件名 private ILogNet LogNet; // 日志对象 private string m_JsonArrayContent = "[]"; // 缓存数据 private int m_filesCount = 0; // 文件数量 private SimpleHybirdLock hybirdLock = new SimpleHybirdLock(); // 简单混合锁 private HslAsyncCoordinator coordinatorCacheJsonArray; // 乐观并发模型 private List<GroupFileItem> m_files; // 文件队列 private string m_filePath; // 文件路径 #endregion } }