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
}
}