using HslCommunication.Core; using HslCommunication.LogNet; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; namespace HslCommunication.Enthernet { /// /// 文件集容器,绑定一个文件夹的文件信息组 /// public class GroupFileContainer { #region Constructor /// /// 实例化一个新的数据管理容器 /// /// 日志记录对象,可以为空 /// 文件的路径 public GroupFileContainer( ILogNet logNet, string path ) { LogNet = logNet; GroupFileContainerLoadByPath( path ); } #endregion #region Public Members /// /// 包含所有文件列表信息的json文本缓存 /// public string JsonArrayContent { get { return m_JsonArrayContent; } } /// /// 获取文件的数量 /// public int FileCount { get { return m_filesCount; } } #endregion #region Event Handle private void OnFileCountChanged( ) { FileCountChanged?.Invoke( m_filesCount ); } /// /// 当文件数量发生变化的时候触发的事件 /// public event Action FileCountChanged; #endregion #region Upload Download Delete /// /// 下载文件时调用 /// /// 文件的实际名称 /// 文件名映射过去的实际的文件名字 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; } /// /// 上传文件时掉用 /// /// 文件名,带后缀,不带任何的路径 /// 文件的大小 /// 文件映射名称 /// 文件的拥有者 /// 文件的额外描述 /// 映射的文件名称 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; } /// /// 删除一个文件信息 /// /// 实际的文件名称 /// 映射之后的文件名 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 /// /// 缓存JSON文本的方法,该机制使用乐观并发模型完成 /// 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( ); } /// /// 从目录进行加载数据,必须实例化的时候加载,加载失败会导致系统异常,旧的文件丢失 /// /// 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>( ); } } catch (Exception ex) { LogNet?.WriteException( "GroupFileContainer", "Load files txt failed,", ex ); } } if (m_files == null) { m_files = new List( ); } 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 m_files; // 文件队列 private string m_filePath; // 文件路径 #endregion } }