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(json); } catch (Exception ex) { //SendMessage.SendInfo($"加载配置文件失败:{ex.Message}", Color.Red); return null; } } /// /// 开始上传文件 /// 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); } } } /// /// 上传文件到ftp /// /// public async void UploadToFtp(string path) { if (_config.Open) { try { await Task.Run(() => { List files = new List(); 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 ListFilesOnFtp(string remoteDir) { var files = new List(); 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 async Task CompressionImage(string sn,string currentPro) { if (_config.Open) { try { string zipPath = ""; await Task.Run(() => { zipPath = $"{_config.ImagePath}\\{sn}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.zip";//生成的zip文件路径 string sourcePath = $"{_config.ImagePath}\\{DateTime.Now.ToString("yyyy-MM")}\\{DateTime.Now.ToString("MM-dd")}\\{currentPro}\\{sn}"; ZipFile.CreateFromDirectory(sourcePath, zipPath); }); return zipPath; } catch (Exception ex) { LogHelper.WriteLogError($"压缩图片文件时出错", ex); return ""; } } return ""; } #endregion } }