123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- using System;
- using System.IO;
- using System.Linq;
- using System.Threading;
- using System.Threading.Tasks;
- using Vinno.FIS.TRTCClient.Common.Log;
- namespace Vinno.FIS.TRTCClient.Common.FileTransfer
- {
- public class FileTransferReader : IDisposable
- {
- private readonly CancellationTokenSource _cts;
- private readonly Task _task;
- private bool _disposed;
- private byte[] _currentByteArray;
- private bool _hasReserveFolder => !string.IsNullOrEmpty(ReserveStorageFolderPath);
- /// <summary>
- /// Name Of File Reader and Folder Name
- /// </summary>
- public string Name { get; private set; }
- /// <summary>
- /// Parent Folder Name
- /// </summary>
- public string ParentFolderName { get; private set; }
- /// <summary>
- /// Parent Folder Path
- /// </summary>
- public string ParentFolderPath { get; private set; }
- /// <summary>
- /// Folder Storage Path
- /// </summary>
- public string StorageFolderPath { get; private set; }
- /// <summary>
- /// Basic Folder under FIS Folder
- /// </summary>
- public string ImageTransferBaseFolderPath { get; private set; }
- /// <summary>
- /// 预留文件夹路径
- /// </summary>
- public string ReserveStorageFolderPath { get; private set; }
- /// <summary>
- /// Raised when log msg throw
- /// </summary>
- public event EventHandler<LogEventArgs> LogMsgThrow;
- public event EventHandler<byte[]> DataReceived;
- public FileTransferReader(string name, string parentFolderName, string fisFolderPath, string reserveName)
- {
- Name = name;
- ParentFolderName = parentFolderName;
- ImageTransferBaseFolderPath = Path.Combine(fisFolderPath, FISTRTCConsts.DataTransferFolder);
- ParentFolderPath = Path.Combine(ImageTransferBaseFolderPath, ParentFolderName);
- StorageFolderPath = Path.Combine(ParentFolderPath, Name);
- if (!string.IsNullOrEmpty(reserveName))
- {
- ReserveStorageFolderPath = Path.Combine(ParentFolderPath, reserveName);
- }
- CreateDirectory(ImageTransferBaseFolderPath);
- CreateDirectory(ParentFolderPath);
- CreateDirectory(StorageFolderPath);
- if (_hasReserveFolder)
- {
- CreateDirectory(ReserveStorageFolderPath);
- var existFiles = Directory.GetFiles(ReserveStorageFolderPath);
- if (existFiles.Length > 0)
- {
- foreach (var existFile in existFiles.OrderBy(x => x))
- {
- var fileName = Path.GetFileName(existFile);
- var copyFilePath = Path.Combine(StorageFolderPath, fileName);
- File.Copy(existFile, copyFilePath, true);
- }
- }
- }
- _cts = new CancellationTokenSource();
- _currentByteArray = new byte[0];
- }
- private void CreateDirectory(string directory)
- {
- if (!Directory.Exists(directory))
- {
- Directory.CreateDirectory(directory);
- }
- }
- public void StartContinuousRead()
- {
- Task.Run(() =>
- {
- while (!_cts.IsCancellationRequested && !_disposed)
- {
- try
- {
- if (!Directory.Exists(StorageFolderPath))
- {
- break;
- }
- var files = Directory.GetFiles(StorageFolderPath, "*.fis");
- var oldestFile = files.OrderBy(x => x).FirstOrDefault();
- if (oldestFile == null)
- {
- Thread.Sleep(100);
- continue;
- }
- try
- {
- using (FileStream fileStream = new FileStream(oldestFile, FileMode.Open, FileAccess.Read))
- {
- using (BinaryReader reader = new BinaryReader(fileStream))
- {
- var dataLength = reader.ReadInt32();
- if (_currentByteArray == null)
- {
- _currentByteArray = new byte[dataLength];
- }
- if (_currentByteArray.Length != dataLength)
- {
- Array.Resize(ref _currentByteArray, dataLength);
- }
- _currentByteArray = reader.ReadBytes(dataLength);
- }
- }
- }
- catch (Exception ex)
- {
- LogMsgThrow?.Invoke(this, new LogEventArgs(DeviceLogCategory.Error, $"FileTransferReader: {Name} ReadContinuous Error:{ex}"));
- }
- finally
- {
- DeleteFile(oldestFile);
- }
- DataReceived?.Invoke(this, _currentByteArray);
- }
- catch (Exception ex)
- {
- if (!((ex is FileNotFoundException) || (ex is DirectoryNotFoundException)))
- {
- LogMsgThrow?.Invoke(this, new LogEventArgs(DeviceLogCategory.Error, $"FileTransferReader: {Name} ReadContinuous Error:{ex}"));
- }
- }
- }
- }, _cts.Token);
- }
- /// <summary>
- /// Delete file
- /// </summary>
- /// <param name="filePath">The file to be deleted.</param>
- private void DeleteFile(string filePath)
- {
- if (string.IsNullOrEmpty(filePath))
- {
- return;
- }
- try
- {
- if (File.Exists(filePath))
- {
- File.SetAttributes(filePath, FileAttributes.Normal);
- File.Delete(filePath);
- }
- }
- catch (Exception ex)
- {
- LogMsgThrow?.Invoke(this, new LogEventArgs(DeviceLogCategory.Error, $"Exception when delete file {filePath},detail:{ex}"));
- }
- }
- /// <summary>
- /// 用于写一个,读一个
- /// </summary>
- /// <param name="dataLength"></param>
- /// <returns></returns>
- public byte[] ReadFromFile(int dataLength)
- {
- try
- {
- if (_disposed || !Directory.Exists(StorageFolderPath))
- {
- return null;
- }
- var files = Directory.GetFiles(StorageFolderPath, "*.fis");
- var oldestFile = files.OrderBy(x => x).FirstOrDefault();
- if (oldestFile == null)
- {
- return null;
- }
- try
- {
- using (FileStream fileStream = new FileStream(oldestFile, FileMode.Open, FileAccess.Read))
- {
- using (BinaryReader reader = new BinaryReader(fileStream))
- {
- if (_currentByteArray.Length != dataLength)
- {
- Array.Resize(ref _currentByteArray, dataLength);
- }
- _currentByteArray = reader.ReadBytes(dataLength);
- }
- }
- }
- catch (Exception ex)
- {
- LogMsgThrow?.Invoke(this, new LogEventArgs(DeviceLogCategory.Error, $"FileTransferReader: {Name} ReadFromFile Error:{ex}"));
- }
- finally
- {
- DeleteFile(oldestFile);
- }
- return _currentByteArray;
- }
- catch (Exception ex)
- {
- if (!((ex is FileNotFoundException) || (ex is DirectoryNotFoundException)))
- {
- LogMsgThrow?.Invoke(this, new LogEventArgs(DeviceLogCategory.Error, $"FileTransferReader: {Name} ReadFromFile Error:{ex}"));
- }
- return null;
- }
- }
- public void Dispose()
- {
- try
- {
- if (_disposed)
- {
- return;
- }
- _cts.Cancel();
- try
- {
- _task?.Wait(200);//因Task在Wait过程中Cancel有几率会出错
- }
- catch
- {
- }
- _disposed = true;
- LogMsgThrow?.Invoke(this, new LogEventArgs(DeviceLogCategory.Info, $"FileTransferReader:{Name} Dispose Success"));
- }
- catch (Exception ex)
- {
- LogMsgThrow?.Invoke(this, new LogEventArgs(DeviceLogCategory.Error, $"FileTransferReader:{Name} Dispose Error:{ex}"));
- }
- }
- }
- }
|