| | |
| | | //using Microsoft.Data.SqlClient; |
| | | //using NPOI.HSSF.Record; |
| | | //using SkiaSharp; |
| | | //using System; |
| | | //using System.Collections.Generic; |
| | | //using System.Linq; |
| | | //using System.Linq.Expressions; |
| | | //using System.Text; |
| | | //using System.Threading.Tasks; |
| | | //using WIDESEAWCS_Core.BaseServices; |
| | | //using WIDESEAWCS_ISystemRepository; |
| | | //using WIDESEAWCS_ISystemServices; |
| | | //using WIDESEAWCS_Model.Models; |
| | | |
| | | //namespace WIDESEAWCS_SystemServices |
| | | //{ |
| | | // public class Sys_LogService : ServiceBase<Sys_Log, ISys_LogRepository>, ISys_LogService |
| | | // { |
| | | // private static DateTime? _lastExecutionDate = null; |
| | | // private readonly object _lock = new object(); |
| | | // private const string DbName = "WIDESEA_HF"; |
| | | // private const long MaxMdfSizeBytes = 8L * 1024 * 1024 * 1024; // 8GB |
| | | // private const int TargetShrinkSizeMB = 4500; // 4.5GB |
| | | |
| | | // public Sys_LogService(ISys_LogRepository BaseDal) : base(BaseDal) |
| | | // { |
| | | |
| | | // } |
| | | |
| | | // public void DeleteOldLogs() |
| | | // { |
| | | // // 使ç¨éç¡®ä¿çº¿ç¨å®å
¨ |
| | | // lock (_lock) |
| | | // { |
| | | // var today = DateTime.Today; |
| | | |
| | | // // æ£æ¥ä»å¤©æ¯å¦å·²ç»æ§è¡è¿ |
| | | // if (_lastExecutionDate.HasValue && _lastExecutionDate.Value.Date == today) |
| | | // { |
| | | // return; |
| | | // } |
| | | // try |
| | | // { |
| | | // // 计ç®3个æåçæ¥æ |
| | | // var threeMonthsAgo = DateTime.Now.AddMonths(-3); |
| | | // // 计ç®3天åçæ¥æ |
| | | // var sevenDaysAgo = DateTime.Now.AddDays(-3); |
| | | // // ç¹å®URL |
| | | // var specificUrl = "http://11.2.30.141:10870/interfaces/api/amr/robotQuery"; |
| | | |
| | | // // æå»ºå 餿¡ä»¶ï¼3个æåçæ¥å¿ æ (3天åä¸URL为ç¹å®å°åçæ¥å¿) |
| | | // var result = BaseDal.Db.Deleteable<Sys_Log>() |
| | | // .Where(log => log.EndDate < threeMonthsAgo || |
| | | // (log.EndDate < sevenDaysAgo && log.Url == specificUrl)) |
| | | // .ExecuteCommand(); |
| | | // // æ´æ°æåæ§è¡æ¥æä¸ºä»å¤© |
| | | // _lastExecutionDate = today; |
| | | // } |
| | | // catch (Exception ex) |
| | | // { |
| | | // Console.WriteLine($"æ§è¡æ¥å¿æ¸
çæ¶åçé误ï¼{ex.Message}"); |
| | | // // åçé误æ¶ä¸æ´æ°æåæ§è¡æ¥æï¼ä»¥ä¾¿éè¯ |
| | | // } |
| | | // } |
| | | // } |
| | | // // 15天æ§è¡ä¸æ¬¡ææå¤©2ç¹ |
| | | // public void CheckAndManageFileSize() |
| | | // { |
| | | // try |
| | | // { |
| | | |
| | | // // --æ£æ¥æ°æ®åºæä»¶ç©ºé´ä½¿ç¨æ
åµ |
| | | // //SELECT |
| | | // // name AS[æä»¶é»è¾å], |
| | | // // physical_name AS[ç©çè·¯å¾], |
| | | // // size/ 128.0 AS[å½å大å°MB], |
| | | // // FILEPROPERTY(name, 'SpaceUsed') / 128.0 AS[å·²ç¨ç©ºé´MB], |
| | | // // size / 128.0 - FILEPROPERTY(name, 'SpaceUsed') / 128.0 AS[å¯ç¨ç©ºé´MB], |
| | | // // growth / 128 AS[å¢é¿éMB], |
| | | // // CASE is_percent_growth |
| | | // // WHEN 1 THEN CAST(growth AS VARCHAR) +'%' |
| | | // // ELSE CAST(growth/ 128 AS VARCHAR) +'MB' |
| | | // // END AS[å¢é¿æ¹å¼] |
| | | // //FROM sys.database_files; |
| | | // using (var connection = new SqlConnection("Data Source=.;Initial Catalog=WIDESEA_HF;User ID=sa;Password=123456;Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False")) |
| | | // { |
| | | // connection.Open(); |
| | | |
| | | // // æ£æ¥æ°æ®åºæä»¶å¤§å° |
| | | // var sizeCheckSql = @"SELECT name AS [æä»¶é»è¾å], size/128.0 AS [å½å大å°MB], FILEPROPERTY(name, 'SpaceUsed')/128.0 AS [å·²ç¨ç©ºé´MB] FROM sys.database_files WHERE name = @dbName"; |
| | | |
| | | // using (var command = new SqlCommand(sizeCheckSql, connection)) |
| | | // { |
| | | // command.Parameters.AddWithValue("@dbName", DbName); |
| | | // using (var reader = command.ExecuteReader()) |
| | | // { |
| | | // if (reader.Read()) |
| | | // { |
| | | // double currentSizeMB = Convert.ToDouble(reader["å½å大å°MB"]); |
| | | // double usedSpaceMB = Convert.ToDouble(reader["å·²ç¨ç©ºé´MB"]); |
| | | |
| | | // if (currentSizeMB > MaxMdfSizeBytes / (1024 * 1024)) |
| | | // { |
| | | // // æ§è¡æ¶ç¼©æ°æ®åº |
| | | |
| | | // }else |
| | | // { |
| | | // // æ´çç¢ç>30% |
| | | |
| | | // } |
| | | // } |
| | | // } |
| | | // } |
| | | // } |
| | | // } |
| | | // catch (Exception ex) |
| | | // { |
| | | // throw new Exception($"æä»¶çæ§å¤±è´¥: {ex.Message}"); |
| | | // } |
| | | // } |
| | | |
| | | |
| | | // } |
| | | //} |
| | | using Microsoft.Data.SqlClient; |
| | | using Microsoft.Data.SqlClient; |
| | | using NPOI.HSSF.Record; |
| | | using SkiaSharp; |
| | | using System; |
| | |
| | | { |
| | | private static DateTime? _lastExecutionDate = null; |
| | | private static DateTime? _lastFileSizeCheckDate = null; |
| | | private static DateTime? _lastBackupDate = null; |
| | | private readonly object _lock = new object(); |
| | | private readonly object _fileSizeLock = new object(); |
| | | private readonly object _backupLock = new object(); |
| | | |
| | | private const string DbName = "WIDESEA_HF"; |
| | | private const string ConnectionString = "Data Source=11.2.30.112;Initial Catalog=WIDESEA_HF;User ID=kuka;Password=kuka;Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"; |
| | | private const long MaxMdfSizeBytes = 7L * 1024 * 1024 * 1024; // 7GB |
| | | private const int TargetShrinkSizeMB = 4500; // 4.5GB |
| | | private const double FragmentationThreshold = 30.0; // 30%ç¢ççéå¼ |
| | | private const int MaintenanceIntervalDays = 15; // 15天æ§è¡ä¸æ¬¡ |
| | | private const int BackupRetentionDays = 30; // å¤ä»½ä¿ç30天 |
| | | private static readonly string BackupBasePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DatabaseBackups"); // å¤ä»½æä»¶åå¨ç®å½ |
| | | private const bool UseBackupCompression = true; // æ¯å¦ä½¿ç¨å¤ä»½å缩 |
| | | private const bool VerifyBackup = true; // æ¯å¦éªè¯å¤ä»½ |
| | | private const int MaxBackupRetryCount = 3; // æå¤§éè¯æ¬¡æ° |
| | | private const int BackupTimeoutSeconds = 7200; // å¤ä»½è¶
æ¶æ¶é´ï¼ç§ï¼ |
| | | |
| | | public Sys_LogService(ISys_LogRepository BaseDal) : base(BaseDal) |
| | | { |
| | | // ç¡®ä¿å¤ä»½ç®å½åå¨ |
| | | //EnsureBackupDirectory(); |
| | | } |
| | | |
| | | private void EnsureBackupDirectory() |
| | | { |
| | | try |
| | | { |
| | | if (!Directory.Exists(BackupBasePath)) |
| | | { |
| | | Directory.CreateDirectory(BackupBasePath); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"å建å¤ä»½ç®å½å¤±è´¥: {ex.Message}"); |
| | | throw; |
| | | } |
| | | } |
| | | |
| | | public void DeleteOldLogs() |
| | |
| | | } |
| | | try |
| | | { |
| | | var result = BaseDal.Db.Deleteable<Sys_Log>().ExecuteCommand(); |
| | | //// 计ç®3个æåçæ¥æ |
| | | //var threeMonthsAgo = DateTime.Now.AddMonths(-3); |
| | | //// 计ç®3天åçæ¥æ |
| | | //var threeDaysAgo = DateTime.Now.AddDays(-3); |
| | | //// ç¹å®URL |
| | | //var specificUrl = "http://11.2.30.141:10870/interfaces/api/amr/robotQuery"; |
| | | //var anonUrl = "http://11.2.30.111/anon/api/kuka/drivestatus"; |
| | | |
| | | //// æå»ºå 餿¡ä»¶ï¼3个æåçæ¥å¿ æ (3天åä¸URL为ç¹å®å°åçæ¥å¿) |
| | | //var result = BaseDal.Db.Deleteable<Sys_Log>() |
| | | // .Where(log => log.EndDate < threeMonthsAgo || |
| | | // (log.EndDate < threeDaysAgo && (log.Url == specificUrl || log.Url == anonUrl))) |
| | | // .ExecuteCommand(); |
| | | // å é¤5天åçæ¥å¿ |
| | | var result = BaseDal.Db.Deleteable<Sys_Log>() |
| | | .Where(log => log.EndDate < DateTime.Now.AddDays(-4)) |
| | | .ExecuteCommand(); |
| | | // æ´æ°æåæ§è¡æ¥æä¸ºä»å¤© |
| | | _lastExecutionDate = today; |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | // 15天æ§è¡ä¸æ¬¡ææå¤©2ç¹ |
| | | // æ¯å¨ææå¤©2ç¹æ§è¡ä¸æ¬¡ |
| | | public void CheckAndManageFileSize() |
| | | { |
| | | // æ£æ¥æ¯å¦ç¬¦åæ§è¡æ¡ä»¶ï¼ææå¤©ã2ç¹å·¦å³ãè·ç¦»ä¸æ¬¡æ§è¡è³å°15天 |
| | | //if (!ShouldExecuteMaintenance()) |
| | | //{ |
| | | // return; |
| | | //} |
| | | |
| | | try |
| | | { |
| | | using (var connection = new SqlConnection(ConnectionString)) |
| | | { |
| | | connection.Open(); |
| | | |
| | | // 1. å¤ä»½æ°æ®åº |
| | | //BackupDatabase(); |
| | | |
| | | // 2. æ£æ¥æ°æ®åºæä»¶å¤§å° |
| | | // 1. æ£æ¥æ°æ®åºæä»¶å¤§å° |
| | | CheckDatabaseFileSize(connection); |
| | | |
| | | // 3. æ£æ¥å¹¶å¤çç´¢å¼ç¢ç |
| | | // 2. æ£æ¥å¹¶å¤çç´¢å¼ç¢ç |
| | | CheckAndHandleIndexFragmentation(connection); |
| | | |
| | | // 4. æ´æ°ç»è®¡ä¿¡æ¯ |
| | | // 3. æ´æ°ç»è®¡ä¿¡æ¯ |
| | | UpdateStatistics(connection); |
| | | |
| | | // 5. æ¸
çæ§å¤ä»½ |
| | | //CleanupOldBackups(); |
| | | |
| | | // æ´æ°æåæ£æ¥æ¥æ |
| | | lock (_fileSizeLock) |
| | |
| | | } |
| | | } |
| | | |
| | | public void BackupDatabase() |
| | | { |
| | | lock (_backupLock) |
| | | { |
| | | try |
| | | { |
| | | var today = DateTime.Today; |
| | | // æ£æ¥ä»å¤©æ¯å¦å·²ç»å¤ä»½è¿ |
| | | if (_lastBackupDate.HasValue && _lastBackupDate.Value.Date == today) |
| | | { |
| | | return; |
| | | } |
| | | var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss"); |
| | | var backupFileName = $"{DbName}_Full_{timestamp}.bak"; |
| | | var backupFilePath = Path.Combine(BackupBasePath, backupFileName); |
| | | |
| | | using (var connection = new SqlConnection(ConnectionString)) |
| | | { |
| | | connection.Open(); |
| | | // è·åæ°æ®åºæä»¶ä¿¡æ¯ï¼è®¡ç®å¤ä»½æä»¶å¤§å° |
| | | var dbSizeQuery = @" |
| | | SELECT |
| | | SUM(size/128.0) AS TotalSizeMB, |
| | | SUM(FILEPROPERTY(name, 'SpaceUsed')/128.0) AS UsedSizeMB, |
| | | COUNT(*) AS FileCount |
| | | FROM sys.database_files |
| | | WHERE type IN (0, 1)"; // æ°æ®æä»¶åæ¥å¿æä»¶ |
| | | |
| | | double totalSizeMB = 0; |
| | | double usedSizeMB = 0; |
| | | int fileCount = 0; |
| | | |
| | | using (var cmd = new SqlCommand(dbSizeQuery, connection)) |
| | | using (var reader = cmd.ExecuteReader()) |
| | | { |
| | | if (reader.Read()) |
| | | { |
| | | totalSizeMB = Convert.ToDouble(reader["TotalSizeMB"]); |
| | | usedSizeMB = Convert.ToDouble(reader["UsedSizeMB"]); |
| | | fileCount = Convert.ToInt32(reader["FileCount"]); |
| | | } |
| | | } |
| | | // æå»ºå¤ä»½SQLè¯å¥ |
| | | var backupSql = BuildBackupSql(backupFilePath); |
| | | |
| | | // æ§è¡å¤ä»½ï¼å¸¦éè¯æºå¶ï¼ |
| | | ExecuteBackupWithRetry(connection, backupSql, backupFilePath); |
| | | |
| | | // éªè¯å¤ä»½æä»¶ |
| | | if (VerifyBackup) |
| | | { |
| | | VerifyBackupFile(connection, backupFilePath); |
| | | } |
| | | |
| | | // æ´æ°æåå¤ä»½æ¥æ |
| | | _lastBackupDate = DateTime.Now; |
| | | |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"æ°æ®åºå¤ä»½å¤±è´¥: {ex.Message}"); |
| | | throw new Exception($"æ°æ®åºå¤ä»½å¤±è´¥: {ex.Message}", ex); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private string BuildBackupSql(string backupFilePath) |
| | | { |
| | | var compressionOption = UseBackupCompression ? "COMPRESSION" : "NO_COMPRESSION"; |
| | | var verifyOption = VerifyBackup ? ", CHECKSUM" : ""; |
| | | |
| | | return $@" |
| | | BACKUP DATABASE [{DbName}] |
| | | TO DISK = '{backupFilePath.Replace("'", "''")}' |
| | | WITH {compressionOption} |
| | | {verifyOption} |
| | | , STATS = 5 |
| | | , DESCRIPTION = 'Full database backup created by automated maintenance on {DateTime.Now:yyyy-MM-dd HH:mm:ss}' |
| | | , MAXTRANSFERSIZE = 4194304 |
| | | , BLOCKSIZE = 65536 |
| | | , BUFFERCOUNT = 10"; |
| | | } |
| | | |
| | | private void ExecuteBackupWithRetry(SqlConnection connection, string backupSql, string backupFilePath) |
| | | { |
| | | int retryCount = 0; |
| | | while (retryCount < MaxBackupRetryCount) |
| | | { |
| | | try |
| | | { |
| | | |
| | | using (var cmd = new SqlCommand(backupSql, connection)) |
| | | { |
| | | cmd.CommandTimeout = BackupTimeoutSeconds; |
| | | |
| | | var rowsAffected = cmd.ExecuteNonQuery(); |
| | | return; // æååéåº |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | retryCount++; |
| | | |
| | | if (retryCount >= MaxBackupRetryCount) |
| | | { |
| | | // å é¤å¯è½æåçå¤ä»½æä»¶ |
| | | try |
| | | { |
| | | if (File.Exists(backupFilePath)) |
| | | { |
| | | File.Delete(backupFilePath); |
| | | } |
| | | } |
| | | catch { } |
| | | |
| | | throw new Exception($"å¤ä»½å¤±è´¥ï¼å·²è¾¾å°æå¤§éè¯æ¬¡æ°({MaxBackupRetryCount}次): {ex.Message}", ex); |
| | | } |
| | | |
| | | Console.WriteLine($"å¤ä»½å¤±è´¥ï¼{MaxBackupRetryCount - retryCount}次éè¯æºä¼: {ex.Message}"); |
| | | Thread.Sleep(5000); // çå¾
5ç§åéè¯ |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void VerifyBackupFile(SqlConnection connection, string backupFilePath) |
| | | { |
| | | try |
| | | { |
| | | |
| | | var verifySql = $@" |
| | | RESTORE VERIFYONLY |
| | | FROM DISK = '{backupFilePath.Replace("'", "''")}' |
| | | WITH CHECKSUM"; |
| | | |
| | | using (var cmd = new SqlCommand(verifySql, connection)) |
| | | { |
| | | cmd.CommandTimeout = 300; // 5åéè¶
æ¶ |
| | | cmd.ExecuteNonQuery(); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | // éªè¯å¤±è´¥æ¶å é¤å¤ä»½æä»¶ |
| | | try |
| | | { |
| | | if (File.Exists(backupFilePath)) |
| | | { |
| | | File.Delete(backupFilePath); |
| | | } |
| | | } |
| | | catch { } |
| | | |
| | | throw new Exception($"å¤ä»½æä»¶éªè¯å¤±è´¥: {ex.Message}", ex); |
| | | } |
| | | } |
| | | |
| | | private void CleanupOldBackups() |
| | | { |
| | | try |
| | | { |
| | | |
| | | if (!Directory.Exists(BackupBasePath)) |
| | | { |
| | | Console.WriteLine("å¤ä»½ç®å½ä¸åå¨ï¼è·³è¿æ¸
ç"); |
| | | return; |
| | | } |
| | | |
| | | var cutoffDate = DateTime.Now.AddDays(-BackupRetentionDays); |
| | | var backupFiles = Directory.GetFiles(BackupBasePath, $"{DbName}_Full_*.bak"); |
| | | int deletedCount = 0; |
| | | |
| | | foreach (var file in backupFiles) |
| | | { |
| | | try |
| | | { |
| | | var fileInfo = new FileInfo(file); |
| | | if (fileInfo.CreationTime < cutoffDate) |
| | | { |
| | | fileInfo.Delete(); |
| | | deletedCount++; |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"å é¤å¤ä»½æä»¶ {file} æ¶åºé: {ex.Message}"); |
| | | // ç»§ç»å¤çå
¶ä»æä»¶ |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"æ¸
çæ§å¤ä»½æ¶åºé: {ex.Message}"); |
| | | // 䏿åºå¼å¸¸ï¼é¿å
å½±å主æµç¨ |
| | | } |
| | | } |
| | | |
| | | private bool ShouldExecuteMaintenance() |
| | | { |
| | | lock (_fileSizeLock) |
| | |
| | | { |
| | | return false; |
| | | } |
| | | // æ£æ¥æ¶é´æ¯å¦æ¯1ç¹å·¦å³ï¼å
许1:00-1:59ï¼ |
| | | if (now.Hour != 1 && now.Hour != 2) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | // æ£æ¥æ¯å¦å·²ç»æ§è¡è¿ |
| | | // æ£æ¥ä»å¤©æ¯å¦å·²ç»æ§è¡è¿ |
| | | if (_lastFileSizeCheckDate.HasValue) |
| | | { |
| | | // æ£æ¥è·ç¦»ä¸æ¬¡æ§è¡æ¯å¦æ»¡è¶³15天é´é |
| | | var daysSinceLastCheck = (now - _lastFileSizeCheckDate.Value).TotalDays; |
| | | if (daysSinceLastCheck < MaintenanceIntervalDays) |
| | | // æ£æ¥æ¯å¦å¨ä»å¤©çåä¸å°æ¶å
æ§è¡è¿ï¼é¿å
é夿§è¡ï¼ |
| | | if (_lastFileSizeCheckDate.Value.Date == now.Date) |
| | | { |
| | | // å¦æå·²ç»æ§è¡è¿ï¼è·³è¿ |
| | | return false; |
| | | } |
| | | } |
| | |
| | | double usedSpaceMB = Convert.ToDouble(reader["å·²ç¨ç©ºé´MB"]); |
| | | double freeSpaceMB = Convert.ToDouble(reader["å¯ç¨ç©ºé´MB"]); |
| | | |
| | | |
| | | // æ£æ¥æ¯å¦éè¦æ¶ç¼© |
| | | if (currentSizeMB * 1024 * 1024 > MaxMdfSizeBytes) |
| | | { |
| | | Console.WriteLine("æ°æ®åºæä»¶è¶
è¿8GBï¼å¼å§æ¶ç¼©..."); |
| | | Console.WriteLine("æ°æ®åºæä»¶è¶
è¿7GBï¼å¼å§æ¶ç¼©..."); |
| | | ShrinkDatabaseFile(connection, logicalName); |
| | | } |
| | | } |
| | |
| | | { |
| | | try |
| | | { |
| | | |
| | | // æ¶ç¼©æ°æ®åºæä»¶ |
| | | string shrinkSql = $"DBCC SHRINKFILE (N'{logicalName}', {TargetShrinkSizeMB})"; |
| | | using (var command = new SqlCommand(shrinkSql, connection)) |
| | |
| | | { |
| | | try |
| | | { |
| | | |
| | | // æ¥è¯¢ææè¡¨çç´¢å¼ç¢çç |
| | | string fragmentationSql = @" |
| | | SELECT |
| | |
| | | // å¤çéè¦éæ°ç»ç»çç´¢å¼ |
| | | if (indexesToReorganize.Any()) |
| | | { |
| | | |
| | | foreach (var index in indexesToReorganize) |
| | | { |
| | | ReorganizeIndex(connection, index.TableName, index.IndexName); |
| | |
| | | throw; |
| | | } |
| | | } |
| | | |
| | | private void UpdateStatistics(SqlConnection connection) |
| | | { |
| | | try |
| | |
| | | throw; |
| | | } |
| | | } |
| | | |
| | | // æä¾ä¸ä¸ªæ¹æ³ä¾ä»»å¡è°åº¦å¨è°ç¨ |
| | | public void ScheduleDatabaseMaintenance() |
| | | { |
| | |
| | | { |
| | | // 1. å 餿§æ¥å¿ |
| | | DeleteOldLogs(); |
| | | // æ£æ¥æ¯å¦ç¬¦åæ§è¡æ¡ä»¶ |
| | | // æ£æ¥æ¯å¦ç¬¦åæ§è¡æ¡ä»¶ï¼æ¯å¨ææå¤©æ§è¡ï¼ |
| | | if (!ShouldExecuteMaintenance()) |
| | | { |
| | | return; |
| | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// éå½è·åæä»¶ä¿¡æ¯ |
| | | /// </summary> |
| | | /// <param name="dirPath"></param> |
| | | /// <returns></returns> |
| | | private DirInfo GetDirInfo(string dirPath) |
| | | { |
| | | //å½åæä»¶å¤¹ |
| | | var dirInfo = new DirInfo(); |
| | | dirInfo.dirName = Path.GetFileName(dirPath); |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// éå½è·åæä»¶ä¿¡æ¯ |
| | | /// </summary> |
| | | /// <param name="dirPath"></param> |
| | | /// <returns></returns> |
| | | private DirInfo GetDirInfo(string dirPath) |
| | | //åæä»¶ |
| | | List<FileDataInfo> files = new List<FileDataInfo>(); |
| | | foreach (var file in Directory.GetFiles(dirPath)) |
| | | { |
| | | //å½åæä»¶å¤¹ |
| | | var dirInfo = new DirInfo(); |
| | | dirInfo.dirName = Path.GetFileName(dirPath); |
| | | |
| | | //åæä»¶ |
| | | List<FileDataInfo> files = new List<FileDataInfo>(); |
| | | foreach (var file in Directory.GetFiles(dirPath)) |
| | | files.Add(new FileDataInfo() |
| | | { |
| | | files.Add(new FileDataInfo() |
| | | { |
| | | filePath = file, |
| | | fileName = Path.GetFileName(file) |
| | | }); |
| | | } |
| | | |
| | | //åæä»¶å¤¹ |
| | | var dirs = Directory.GetDirectories(dirPath); |
| | | dirInfo.dirs = new List<DirInfo>(); |
| | | foreach (var dir in dirs) |
| | | { |
| | | dirInfo.dirs.Add(GetDirInfo(dir)); |
| | | } |
| | | |
| | | //åæä»¶å¤¹ï¼ä¸åç®å½åå¹¶ |
| | | foreach (var file in files) |
| | | { |
| | | dirInfo.dirs.Add(new DirInfo() { dirPath = file.filePath, dirName = file.fileName }); |
| | | } |
| | | return dirInfo; |
| | | filePath = file, |
| | | fileName = Path.GetFileName(file) |
| | | }); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åæ¥å¿æä»¶å表 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public WebResponseContent GetLogList() |
| | | //åæä»¶å¤¹ |
| | | var dirs = Directory.GetDirectories(dirPath); |
| | | dirInfo.dirs = new List<DirInfo>(); |
| | | foreach (var dir in dirs) |
| | | { |
| | | WebResponseContent content = new WebResponseContent(); |
| | | string path = Path.Combine(AppContext.BaseDirectory, "log"); |
| | | if (!Directory.Exists(path)) |
| | | { |
| | | return content.Error("ææ æ¥å¿æä»¶"); |
| | | } |
| | | |
| | | content.Data = GetDirInfo(path); |
| | | content.OK(); |
| | | return content; |
| | | dirInfo.dirs.Add(GetDirInfo(dir)); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åæä»¶å
容 |
| | | /// </summary> |
| | | /// <param name="parm"></param> |
| | | /// <returns></returns> |
| | | public WebResponseContent GetLogData(GetLogParm parm) |
| | | //åæä»¶å¤¹ï¼ä¸åç®å½åå¹¶ |
| | | foreach (var file in files) |
| | | { |
| | | WebResponseContent content = new WebResponseContent(); |
| | | string res = ""; |
| | | //æ¯å¦è¯»åå°æå |
| | | bool isEnd = false; |
| | | long startIndex = 0; |
| | | //æä»¶å¤§å° |
| | | long len = 0; |
| | | try |
| | | { |
| | | if (!File.Exists(parm.path)) |
| | | { |
| | | throw new Exception($"æä»¶{parm.path}ä¸åå¨ï¼"); |
| | | } |
| | | using (FileStream fs = new FileStream(parm.path, FileMode.Open, FileAccess.Read, FileShare.Read)) |
| | | { |
| | | //æå¤§è¯»åå¤§å° |
| | | int maxsize = (int)(1024 * parm.maxsize_KB); |
| | | len = fs.Length; |
| | | long startPos = (long)(len * (parm.percent / 100));//èµ·å§ä½ç½® |
| | | long readLen = len - startPos;//读åé¿åº¦ |
| | | |
| | | //ååå è½½ |
| | | if (parm.topStartPos != 0) |
| | | { |
| | | startPos = parm.topStartPos - maxsize; |
| | | if (startPos < 0) |
| | | { |
| | | //已读å°èµ·å§ä½ |
| | | startPos = 0; |
| | | readLen = parm.topStartPos; |
| | | } |
| | | else |
| | | { |
| | | readLen = maxsize; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | //读å大尿¯å¦è¶
åºæå¤§é¿åº¦ |
| | | if (readLen > maxsize) |
| | | { |
| | | readLen = maxsize; |
| | | } |
| | | else |
| | | { |
| | | isEnd = true; |
| | | } |
| | | } |
| | | |
| | | //å è½½100%ï¼ææå¤§å
容读å |
| | | if (parm.percent == 100) |
| | | { |
| | | if (len < maxsize) |
| | | { |
| | | startPos = 0; |
| | | readLen = len; |
| | | } |
| | | else |
| | | { |
| | | startPos = len - maxsize; |
| | | readLen = maxsize; |
| | | } |
| | | } |
| | | |
| | | fs.Seek(startPos, SeekOrigin.Begin); |
| | | var buffer = new byte[readLen]; |
| | | fs.Read(buffer, 0, (int)readLen); |
| | | |
| | | startIndex = startPos; |
| | | if (startPos != 0 && (parm.percent != 0 || parm.topStartPos != 0)) |
| | | { |
| | | //䏿¯ä»å¤´å è½½ï¼å é¤å¯è½ä¸å®æ´ç第ä¸è¡ |
| | | int skipCount = 0; |
| | | for (int i = 0; i < buffer.Length; i++) |
| | | { |
| | | if (buffer[i] == 10) |
| | | { |
| | | skipCount = i; |
| | | break; |
| | | } |
| | | } |
| | | if (skipCount != 0) |
| | | { |
| | | //廿æ¢è¡ |
| | | skipCount++; |
| | | //䏿¬¡è¯»ååå»¶ |
| | | startIndex += skipCount; |
| | | } |
| | | res = Encoding.UTF8.GetString(buffer.Skip(skipCount).ToArray()); |
| | | } |
| | | else |
| | | { |
| | | res = Encoding.UTF8.GetString(buffer); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | return content.Error(ex.Message); |
| | | } |
| | | return content.OK(data: new { content = res, isEnd, startIndex, len }); |
| | | dirInfo.dirs.Add(new DirInfo() { dirPath = file.filePath, dirName = file.fileName }); |
| | | } |
| | | return dirInfo; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åæ¥å¿æä»¶å表 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public WebResponseContent GetLogList() |
| | | { |
| | | WebResponseContent content = new WebResponseContent(); |
| | | string path = Path.Combine(AppContext.BaseDirectory, "log"); |
| | | if (!Directory.Exists(path)) |
| | | { |
| | | return content.Error("ææ æ¥å¿æä»¶"); |
| | | } |
| | | |
| | | content.Data = GetDirInfo(path); |
| | | content.OK(); |
| | | return content; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åæä»¶å
容 |
| | | /// </summary> |
| | | /// <param name="parm"></param> |
| | | /// <returns></returns> |
| | | public WebResponseContent GetLogData(GetLogParm parm) |
| | | { |
| | | WebResponseContent content = new WebResponseContent(); |
| | | string res = ""; |
| | | //æ¯å¦è¯»åå°æå |
| | | bool isEnd = false; |
| | | long startIndex = 0; |
| | | //æä»¶å¤§å° |
| | | long len = 0; |
| | | try |
| | | { |
| | | if (!File.Exists(parm.path)) |
| | | { |
| | | throw new Exception($"æä»¶{parm.path}ä¸åå¨ï¼"); |
| | | } |
| | | using (FileStream fs = new FileStream(parm.path, FileMode.Open, FileAccess.Read, FileShare.Read)) |
| | | { |
| | | //æå¤§è¯»åå¤§å° |
| | | int maxsize = (int)(1024 * parm.maxsize_KB); |
| | | len = fs.Length; |
| | | long startPos = (long)(len * (parm.percent / 100));//èµ·å§ä½ç½® |
| | | long readLen = len - startPos;//读åé¿åº¦ |
| | | |
| | | //ååå è½½ |
| | | if (parm.topStartPos != 0) |
| | | { |
| | | startPos = parm.topStartPos - maxsize; |
| | | if (startPos < 0) |
| | | { |
| | | //已读å°èµ·å§ä½ |
| | | startPos = 0; |
| | | readLen = parm.topStartPos; |
| | | } |
| | | else |
| | | { |
| | | readLen = maxsize; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | //读å大尿¯å¦è¶
åºæå¤§é¿åº¦ |
| | | if (readLen > maxsize) |
| | | { |
| | | readLen = maxsize; |
| | | } |
| | | else |
| | | { |
| | | isEnd = true; |
| | | } |
| | | } |
| | | |
| | | //å è½½100%ï¼ææå¤§å
容读å |
| | | if (parm.percent == 100) |
| | | { |
| | | if (len < maxsize) |
| | | { |
| | | startPos = 0; |
| | | readLen = len; |
| | | } |
| | | else |
| | | { |
| | | startPos = len - maxsize; |
| | | readLen = maxsize; |
| | | } |
| | | } |
| | | |
| | | fs.Seek(startPos, SeekOrigin.Begin); |
| | | var buffer = new byte[readLen]; |
| | | fs.Read(buffer, 0, (int)readLen); |
| | | |
| | | startIndex = startPos; |
| | | if (startPos != 0 && (parm.percent != 0 || parm.topStartPos != 0)) |
| | | { |
| | | //䏿¯ä»å¤´å è½½ï¼å é¤å¯è½ä¸å®æ´ç第ä¸è¡ |
| | | int skipCount = 0; |
| | | for (int i = 0; i < buffer.Length; i++) |
| | | { |
| | | if (buffer[i] == 10) |
| | | { |
| | | skipCount = i; |
| | | break; |
| | | } |
| | | } |
| | | if (skipCount != 0) |
| | | { |
| | | //廿æ¢è¡ |
| | | skipCount++; |
| | | //䏿¬¡è¯»ååå»¶ |
| | | startIndex += skipCount; |
| | | } |
| | | res = Encoding.UTF8.GetString(buffer.Skip(skipCount).ToArray()); |
| | | } |
| | | else |
| | | { |
| | | res = Encoding.UTF8.GetString(buffer); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | return content.Error(ex.Message); |
| | | } |
| | | return content.OK(data: new { content = res, isEnd, startIndex, len }); |
| | | } |
| | | } |
| | | } |