From 8bbe3084745e815ea2bd0dd9d19c2ccb68aef954 Mon Sep 17 00:00:00 2001 From: ZGGSONG Date: Thu, 9 Dec 2021 10:36:57 +0800 Subject: [PATCH] leon object method --- S3Demo/Model/Uploader/S3UploadOperator.cs | 60 ++++++++++++++++++++++ S3Demo/Model/Uploader/S3UploadRequest.cs | 32 ++++++++++++ S3Demo/Model/Uploader/S3Uploader.cs | 28 ++++++++++ S3Demo/Run.cs | 60 ++++++++++++---------- vendor/KsatLogging.dll | Bin 0 -> 39424 bytes 5 files changed, 154 insertions(+), 26 deletions(-) create mode 100644 S3Demo/Model/Uploader/S3UploadOperator.cs create mode 100644 S3Demo/Model/Uploader/S3UploadRequest.cs create mode 100644 S3Demo/Model/Uploader/S3Uploader.cs create mode 100644 vendor/KsatLogging.dll diff --git a/S3Demo/Model/Uploader/S3UploadOperator.cs b/S3Demo/Model/Uploader/S3UploadOperator.cs new file mode 100644 index 0000000..be0378a --- /dev/null +++ b/S3Demo/Model/Uploader/S3UploadOperator.cs @@ -0,0 +1,60 @@ +using System; +using Ksat.Logging; +using Ksat.Supplyment.Library.Uploader; +using Ksat.Supplyment.Library.Model.Uploader; +using S3Demo.Model.Uploader; + +namespace S3Demo.Uploader +{ + public class S3UploadOperator : IUploaderOperator + { + //Log + private ILogger sLog = LoggerFactory.ForContext(); + public string ConvertCacheToRequest(string cache) + { + return cache; + } + + public string ConvertRequestToCachel(string requestData) + { + return requestData; + } + + public bool ShouldRetryRequest(UploadModel requestModel, out string cancelReason) + { + if (DateTime.Now.Subtract(requestModel.CreateAt).TotalSeconds > 600) + { + cancelReason = "exceed 600s"; + return false; + } + if (requestModel.RetryCount > 5) + { + cancelReason = "exceed 5"; + return false; + } + cancelReason = null; + return true; + } + + public bool ShouldStartRequest(UploadModel requestModel, out string cancelReason) + { + if (DateTime.Now.Subtract(requestModel.CreateAt).TotalSeconds > 600) + { + cancelReason = "exceed 600s"; + return false; + } + if (requestModel.RetryCount > 5) + { + cancelReason = "exceed 5"; + return false; + } + cancelReason = null; + return true; + } + + public IUploaderRequest UploadData(string data) + { + return new S3UploadRequest() { RequestData = data }; + } + } +} diff --git a/S3Demo/Model/Uploader/S3UploadRequest.cs b/S3Demo/Model/Uploader/S3UploadRequest.cs new file mode 100644 index 0000000..6c38df0 --- /dev/null +++ b/S3Demo/Model/Uploader/S3UploadRequest.cs @@ -0,0 +1,32 @@ +using System; +using S3Demo.Uploader; +using Ksat.Supplyment.Library.Uploader; +using Ksat.Supplyment.Library.Model.Uploader; +using Ksat.Logging; + +namespace S3Demo.Model.Uploader +{ + public class S3UploadRequest : IUploaderRequest + { + //Log + private ILogger sLog = LoggerFactory.ForContext(); + + public string RequestData { get; set; } + + public event UploadFinishHandler UploadFinish; + + + public void Cancel() + { + //TODO: + } + + public void Start() + { + var ran = new Random(); + //TODO: + System.Threading.Thread.Sleep(1000); + UploadFinish(this, ran.Next() % 3 == 0, "No reason"); + } + } +} diff --git a/S3Demo/Model/Uploader/S3Uploader.cs b/S3Demo/Model/Uploader/S3Uploader.cs new file mode 100644 index 0000000..c33aee0 --- /dev/null +++ b/S3Demo/Model/Uploader/S3Uploader.cs @@ -0,0 +1,28 @@ +using System; +using Newtonsoft.Json; +using Ksat.Supplyment.Library.Uploader; +using S3Demo.Uploader; + +namespace S3Demo.Model.Uploader +{ + public class S3Uploader + { + private static Uploader mUploader; + private static S3UploadOperator mOperator; + public S3Uploader(string UploadID) + { + mOperator = new S3UploadOperator(); + mUploader = new Uploader(UploadID, mOperator); + } + + public void AddUploadTask(string reqData, string tag) + { + mUploader.AddUploadRequest(reqData, tag); + } + + public void Dispose() + { + mUploader.Dispose(); + } + } +} diff --git a/S3Demo/Run.cs b/S3Demo/Run.cs index 4597b89..3bde81e 100644 --- a/S3Demo/Run.cs +++ b/S3Demo/Run.cs @@ -5,6 +5,7 @@ using Amazon; using Amazon.Runtime; using Amazon.S3; using S3Demo.Model; +using S3Demo.Model.Uploader; using Ksat.Supplyment.Library.Model; using Ksat.Supplyment.Library.Uploader; using Ksat.Supplyment.Library.Model.Uploader; @@ -19,7 +20,7 @@ namespace S3Demo private static BasicAWSCredentials credentials = new BasicAWSCredentials("admin", "admin123."); //private static BasicAWSCredentials credentials = new BasicAWSCredentials("Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG"); private static string bucketName = "minio/test"; - // 受监控的目录,完整目录如:"D:\ClientDir\line01\AOI\20211129\133055851SN001OK.png" + // 受监控的目录,完整目录如:"D:\ClientDir\line01\AOI\20211129\133055851SN001.png" private static string[] paths = { @"D:\ClientDir" }; private static string suffix = "*.png"; @@ -222,38 +223,21 @@ namespace S3Demo } } #endregion + /// - /// 创建文件事件 + /// 创建文件 /// /// /// - /// - /// 主要逻辑 - /// private static async void OnCreated(object sender, FileSystemEventArgs e) { - string path = e.FullPath; - Waiting(path);//等待文件创建完成 - await DisposeFile(path);//处理文件 + Waiting(e.FullPath); + await DisposeFile(e.FullPath); } - - private static async Task DisposeFile(string path) - { - // D:\ClientDir\line01\AOI\20211129\085023891P107CN14T00001.png - string lineName = Path.GetDirectoryName(path).Split('\\')[2]; - string equipmentName = Path.GetDirectoryName(path).Split('\\')[3]; - string date = Path.GetDirectoryName(path).Split('\\')[4]; - string fileName = Path.GetFileName(path); - string datetime = date + fileName.Substring(0, 9); - string dt_fomat = DateTime.ParseExact(datetime, "yyyyMMddHHmmssfff", System.Globalization.CultureInfo.CurrentCulture).ToString("yyyy-MM-dd HH:mm:ss:fff"); - string sn = fileName.Substring(9, 14); - string now = DateTime.Now.ToString("yyyyMMddHHmmssfff"); - String[] tags = new String[] { sn, dt_fomat }; - string S3Path = lineName + "/" + equipmentName + "/" + date + "/" + fileName; - string recv = await ObjectModel.PutObjectsWithTagsAsync(client, bucketName, S3Path, path, tags); - Console.WriteLine(recv); - } - + /// + /// 等待onCreated事件处理完成 + /// + /// 被创建的文件路径 private static void Waiting(string path) { try @@ -273,6 +257,30 @@ namespace S3Demo catch { } } + /// + /// 处理文件 + /// + /// 文件路径 + /// + private static async Task DisposeFile(string path) + { + // D:\ClientDir\line01\AOI\20211129\085023891P107CN14T00001.png + string lineName = Path.GetDirectoryName(path).Split('\\')[2]; + string equipmentName = Path.GetDirectoryName(path).Split('\\')[3]; + string date = Path.GetDirectoryName(path).Split('\\')[4]; + string fileName = Path.GetFileName(path); + string datetime = date + fileName.Substring(0, 9); + string dt_fomat = DateTime.ParseExact(datetime, "yyyyMMddHHmmssfff", System.Globalization.CultureInfo.CurrentCulture).ToString("yyyy-MM-dd HH:mm:ss:fff"); + string sn = fileName.Substring(9, 14); + string now = DateTime.Now.ToString("yyyyMMddHHmmssfff"); + String[] tags = new String[] { sn, dt_fomat }; + string S3Path = lineName + "/" + equipmentName + "/" + date + "/" + fileName; + string recv = await ObjectModel.PutObjectsWithTagsAsync(client, bucketName, S3Path, path, tags); + Console.WriteLine("recv from S3: " + recv); + //引入统一上传方式 + //new S3Uploader(lineName).AddUploadTask(S3Path, sn); + } + /// /// 出现错误 /// diff --git a/vendor/KsatLogging.dll b/vendor/KsatLogging.dll new file mode 100644 index 0000000000000000000000000000000000000000..733498bd85f0a3c3bc1079933415db592db641a1 GIT binary patch literal 39424 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 F{{ZN|DHs3% literal 0 HcmV?d00001