|
|
@@ -0,0 +1,389 @@
|
|
|
+using System.IO.Compression;
|
|
|
+using Newtonsoft.Json;
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.IO;
|
|
|
+using System.Linq;
|
|
|
+using System.Net;
|
|
|
+using System.Text;
|
|
|
+using System.Threading;
|
|
|
+using System.Threading.Tasks;
|
|
|
+using TeamAAS_VP.Models;
|
|
|
+
|
|
|
+namespace TeamAAS_VP.Core
|
|
|
+{
|
|
|
+ public class FtpUploader
|
|
|
+ {
|
|
|
+ //private readonly Timer _timer;
|
|
|
+ //private static readonly Timer _cleanupTimer = new Timer();
|
|
|
+ private ConfigFtp _config;
|
|
|
+ public FtpUploader()
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ string configFilePath = "..//Config//FtpConfig.cfg";
|
|
|
+ //加载配置文件
|
|
|
+ _config = new ConfigFtp();
|
|
|
+ _config = LoadConfiguration(configFilePath);
|
|
|
+ //设置上传定时器
|
|
|
+ //_timer = new Timer(_config.IntervalMinutes * 60 * 1000);
|
|
|
+ //_timer.Elapsed += (s, e) => UploadAllFolders();
|
|
|
+ //_timer.AutoReset = true;
|
|
|
+
|
|
|
+ //// 设置清理定时器
|
|
|
+ //_cleanupTimer.Interval = _config.CleanupIntervalMinutes * 60 * 1000;
|
|
|
+ //_cleanupTimer.Elapsed += (sender, e) => CleanupOldFilesOnFtp();
|
|
|
+ //_cleanupTimer.AutoReset = true;
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public void Start()
|
|
|
+ {
|
|
|
+ if (_config.Open)
|
|
|
+ {
|
|
|
+ Task.Run(async () =>
|
|
|
+ {
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ //_timer.Start();
|
|
|
+ //SendMessage.SendInfo("启动Ftp上传服务...", Color.Black);
|
|
|
+ //立即执行一次
|
|
|
+ UploadAllFolders();
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await Task.Delay(_config.IntervalMinutes * 60 * 1000);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public void Stop()
|
|
|
+ {
|
|
|
+ //_timer.Stop();
|
|
|
+ //SendMessage.SendInfo("Ftp上传服务已停止", Color.Black);
|
|
|
+ }
|
|
|
+ private ConfigFtp LoadConfiguration(string configFilePath)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ string json = File.ReadAllText(configFilePath);
|
|
|
+ return JsonConvert.DeserializeObject<ConfigFtp>(json);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ //SendMessage.SendInfo($"加载配置文件失败:{ex.Message}", Color.Red);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// <summary>
|
|
|
+ /// 开始上传文件
|
|
|
+ /// </summary>
|
|
|
+ public void UploadAllFolders()
|
|
|
+ {
|
|
|
+ Task.Run(() =>
|
|
|
+ {
|
|
|
+ foreach (var localFolder in _config.LocalFolders)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!Directory.Exists(localFolder))
|
|
|
+ {
|
|
|
+ //文件夹不存在
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ var files = Directory.GetFiles(localFolder).ToList();
|
|
|
+ // if (!files.Any())
|
|
|
+ // {
|
|
|
+ //string path1 = localFolder + $"\\{DateTime.Now.ToString("yyyy-MM")}";
|
|
|
+ string path2 = localFolder + $"\\{DateTime.Now.ToString("yyyy-MM")}\\{DateTime.Now.ToString("MM-dd")}\\OK";
|
|
|
+ string path3 = localFolder + $"\\{DateTime.Now.ToString("yyyy-MM")}\\{DateTime.Now.ToString("MM-dd")}\\NG";
|
|
|
+ string path4 = localFolder;
|
|
|
+ //if (Directory.Exists(path1))
|
|
|
+ //{
|
|
|
+ // files = Directory.GetFiles(path1).ToList();
|
|
|
+ // string str1 = string.Join("/", path1.Split('\\').Skip(2));
|
|
|
+ // EnsureFtpDirectoryExists(str1);
|
|
|
+ //}
|
|
|
+ if (Directory.Exists(path2))
|
|
|
+ {
|
|
|
+ var files1 = Directory.GetFiles(path2).ToList();
|
|
|
+ if (Directory.Exists(path3))
|
|
|
+ {
|
|
|
+ var files2 = Directory.GetFiles(path3).ToList();
|
|
|
+ foreach (var item in files2)
|
|
|
+ {
|
|
|
+ files1.Add(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ files = files1;
|
|
|
+ string str2 = string.Join("/", path2.Split('\\').Skip(2));
|
|
|
+ EnsureFtpDirectoryExists(str2);
|
|
|
+ string str3 = string.Join("/", path3.Split('\\').Skip(2));
|
|
|
+ EnsureFtpDirectoryExists(str3);
|
|
|
+ }
|
|
|
+ else if (Directory.Exists(path3))
|
|
|
+ {
|
|
|
+ var files1 = Directory.GetFiles(path3).ToList();
|
|
|
+ files = files1;
|
|
|
+ string str3 = string.Join("/", path3.Split('\\').Skip(2));
|
|
|
+ EnsureFtpDirectoryExists(str3);
|
|
|
+ }
|
|
|
+ else if (Directory.Exists(path4))
|
|
|
+ {
|
|
|
+ files = Directory.GetFiles(path4).ToList();
|
|
|
+ string str4 = string.Join("/", path4.Split('\\').Skip(2));
|
|
|
+ EnsureFtpDirectoryExists(str4);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // SendMessage.SendInfo($"没有找到可上传文件:{localFolder}", Color.Black);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // }
|
|
|
+
|
|
|
+ foreach (var file in files)
|
|
|
+ {
|
|
|
+ UploadFile(file);
|
|
|
+ //CleanupOldFilesOnFtp(file);
|
|
|
+ }
|
|
|
+ files.Clear();
|
|
|
+ Thread.Sleep(500);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogError($"处理文件夹{localFolder}时出错", ex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ private void UploadFile(string localFilePath)
|
|
|
+ {
|
|
|
+ if (_config.Open)
|
|
|
+ {
|
|
|
+ string str = string.Join("/", localFilePath.Split('\\').Skip(2));
|
|
|
+ string fileName = Path.GetFileName(localFilePath);
|
|
|
+ string ftpUri = $"{_config.FtpServer}/{_config.RemotePath}/{str}";
|
|
|
+ try
|
|
|
+ {
|
|
|
+ FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUri);
|
|
|
+ request.Method = WebRequestMethods.Ftp.UploadFile;
|
|
|
+ request.Credentials = new NetworkCredential(_config.Username, _config.Password);
|
|
|
+ using (var fileStream = File.OpenRead(localFilePath))
|
|
|
+ using (Stream ftpStream = request.GetRequestStream())
|
|
|
+ {
|
|
|
+ fileStream.CopyTo(ftpStream);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogError($"上传{fileName}失败", ex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ private void EnsureFtpDirectoryExists(string ftpSubDirectory)
|
|
|
+ {
|
|
|
+ if (_config.Open)
|
|
|
+ {
|
|
|
+ string ftpUri = $"{_config.FtpServer}/{_config.RemotePath}/{ftpSubDirectory}";
|
|
|
+ try
|
|
|
+ {
|
|
|
+ FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUri);
|
|
|
+ request.Method = WebRequestMethods.Ftp.MakeDirectory;
|
|
|
+ request.Credentials = new NetworkCredential(_config.Username, _config.Password);
|
|
|
+ using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
|
|
|
+ {
|
|
|
+ //SendMessage.SendInfo($"创建Ftp目录:{ftpSubDirectory}", Color.Black);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ //SendMessage.SendInfo($"创建目录{ftpSubDirectory}失败:{ex.Message}", Color.Red);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 上传文件到ftp
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="path"></param>
|
|
|
+ public void UploadToFtp(string path)
|
|
|
+ {
|
|
|
+ if (_config.Open)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ Task.Run(() =>
|
|
|
+ {
|
|
|
+ List<string> files = new List<string>();
|
|
|
+ if (Directory.Exists(path))
|
|
|
+ {
|
|
|
+ files = Directory.GetFiles(path).ToList();
|
|
|
+ string str = string.Join("/", path.Split('\\').Skip(2));
|
|
|
+ EnsureFtpDirectoryExists(str);
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach (var file in files)
|
|
|
+ {
|
|
|
+ UploadFile(file);
|
|
|
+ }
|
|
|
+ files.Clear();
|
|
|
+ });
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogError($"上传FTP文件{path}时出错", ex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #region 清理
|
|
|
+ public void CleanupOldFilesOnFtp(string localFilePath)
|
|
|
+ {
|
|
|
+ //Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - 开始执行FTP文件清理任务");
|
|
|
+ var cutoffDate = DateTime.Now.AddDays(-_config.DeleteDay);
|
|
|
+
|
|
|
+ //foreach (var folder in _config.LocalFolders)
|
|
|
+ //{
|
|
|
+ //string remoteDir = string.Join("/", localFilePath.Split('\\').Skip(2));
|
|
|
+ string fileName = Path.GetFileName(localFilePath);
|
|
|
+ //var remoteDir = $"{_config.RemotePath}{folderName}/";
|
|
|
+ string remoteDir = "";
|
|
|
+ ////截取地址中前两个\\保留后面内容
|
|
|
+ //int firstSlashIndex = folder.IndexOf('\\');
|
|
|
+ //int secondSlashIndex = folder.IndexOf('\\', firstSlashIndex + 1);
|
|
|
+ //if (secondSlashIndex >= 0)
|
|
|
+ //{
|
|
|
+ // string result = folder.Substring(secondSlashIndex + 1);
|
|
|
+ // remoteDir = $"{_config.FtpServer}/{_config.RemotePath}/{result}";
|
|
|
+ //}
|
|
|
+
|
|
|
+ //去掉前两个//,并且去掉后面文件名和格式
|
|
|
+ string[] parts = localFilePath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
+ if (parts.Length >= 5) // 确保路径足够长
|
|
|
+ {
|
|
|
+ var middleParts = parts.Skip(3).Take(parts.Length - 4); // 跳过前3部分,去掉最后1部分
|
|
|
+ string result = string.Join("/", middleParts); // 合并成路径
|
|
|
+ remoteDir = result;
|
|
|
+ }
|
|
|
+ try
|
|
|
+ {
|
|
|
+ //获取FTP服务器指定目录下的文件列表,并将结果存储在files变量中。
|
|
|
+ var files = ListFilesOnFtp(remoteDir);
|
|
|
+
|
|
|
+ foreach (var file in files)
|
|
|
+ {
|
|
|
+ if (file.LastModified < cutoffDate)
|
|
|
+ {
|
|
|
+ DeleteFileOnFtp(remoteDir + file.Name);
|
|
|
+ //Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - 已删除FTP旧文件: {remoteDir}{file.Name} (修改时间: {file.LastModified})");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogError($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - 清理FTP目录 {remoteDir} 出错", ex);
|
|
|
+ }
|
|
|
+ //}
|
|
|
+ //Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - FTP文件清理任务完成");
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<FtpFileInfo> ListFilesOnFtp(string remoteDir)
|
|
|
+ {
|
|
|
+ var files = new List<FtpFileInfo>();
|
|
|
+ var uri = new Uri($"{_config.FtpServer}/{_config.RemotePath}/{remoteDir}");//Uri($"{_config.FtpServer}/{remoteDir}");
|
|
|
+
|
|
|
+ var request = (FtpWebRequest)WebRequest.Create(uri);
|
|
|
+ request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
|
|
|
+ request.Credentials = new NetworkCredential(_config.Username, _config.Password);
|
|
|
+ request.UsePassive = true;
|
|
|
+
|
|
|
+ using (var response = (FtpWebResponse)request.GetResponse())
|
|
|
+ using (var stream = response.GetResponseStream())
|
|
|
+ using (var reader = new StreamReader(stream))
|
|
|
+ {
|
|
|
+ string line;
|
|
|
+ while ((line = reader.ReadLine()) != null)
|
|
|
+ {
|
|
|
+ var parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
+ if (parts.Length > 8 && !string.IsNullOrEmpty(parts[8]))
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ var dateStr = $"{parts[5]} {parts[6]} {parts[7]}";
|
|
|
+ if (DateTime.TryParse(dateStr, out var lastModified))
|
|
|
+ {
|
|
|
+ files.Add(new FtpFileInfo
|
|
|
+ {
|
|
|
+ Name = parts[8],
|
|
|
+ LastModified = lastModified
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch
|
|
|
+ {
|
|
|
+ // 忽略解析错误的行
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return files;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void DeleteFileOnFtp(string remoteFilePath)
|
|
|
+ {
|
|
|
+ var uri = new Uri($"{_config.FtpServer}/{_config.RemotePath}/{remoteFilePath}");
|
|
|
+
|
|
|
+ var request = (FtpWebRequest)WebRequest.Create(uri);
|
|
|
+ request.Method = WebRequestMethods.Ftp.DeleteFile;
|
|
|
+ request.Credentials = new NetworkCredential(_config.Username, _config.Password);
|
|
|
+ request.UsePassive = true;
|
|
|
+
|
|
|
+ using (var response = (FtpWebResponse)request.GetResponse())
|
|
|
+ {
|
|
|
+ if (response.StatusCode != FtpStatusCode.FileActionOK)
|
|
|
+ {
|
|
|
+ // throw new Exception($"删除文件失败: {response.StatusCode}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 压缩图片文件夹
|
|
|
+
|
|
|
+ public string CompressionImage(string name)
|
|
|
+ {
|
|
|
+ if (_config.Open)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ string zipPath = "";
|
|
|
+ Task.Run(() =>
|
|
|
+ {
|
|
|
+ zipPath = $"{_config.ImagePath}\\{name}.zip";//生成的zip文件路径
|
|
|
+ ZipFile.CreateFromDirectory(_config.ImagePath, zipPath);
|
|
|
+ });
|
|
|
+ return zipPath;
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogError($"压缩图片文件时出错", ex);
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+ }
|
|
|
+}
|