You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

248 lines
7.8 KiB
C#

using HslCommunication.Core;
using HslCommunication.LogNet;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
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
}
}