Loading src/WatermarkClock/Templates/FileReader.cs +60 −3 Original line number Diff line number Diff line Loading @@ -13,6 +13,12 @@ namespace WatermarkClock.Templates // 匹配 {*...} 整体内容 private readonly Regex _pattern = new Regex(@"\{\*([^}]+)\}", RegexOptions.Compiled); // 缓存:key = "filePath:lineNumber", value = 文件内容(仅缓存成功读取的内容) private readonly Dictionary<string, string> _contentCache = new Dictionary<string, string>(); // 缓存:key = 原始内容(如 "C:\path:1"),value = 解析后的 (path, line) private readonly Dictionary<string, (string path, int line)> _parseCache = new Dictionary<string, (string path, int line)>(); public string Replace(string input) { if (string.IsNullOrEmpty(input)) Loading @@ -23,8 +29,8 @@ namespace WatermarkClock.Templates return _pattern.Replace(input, match => { var content = match.Groups[1].Value; var (filePath, lineNumber) = ParsePathAndLine(content); return ReadFileLine(filePath, lineNumber); var (filePath, lineNumber) = GetParsedPathAndLine(content); return GetFileContent(filePath, lineNumber); }); } catch Loading @@ -33,6 +39,22 @@ namespace WatermarkClock.Templates } } /// <summary> /// 获取解析后的路径和行号(带缓存) /// </summary> private (string path, int line) GetParsedPathAndLine(string content) { if (_parseCache.TryGetValue(content, out var cached)) return cached; var result = ParsePathAndLine(content); _parseCache[content] = result; return result; } /// <summary> /// 解析路径和行号 /// </summary> private (string path, int line) ParsePathAndLine(string content) { // 从末尾查找 :数字 作为行号 Loading @@ -53,6 +75,32 @@ namespace WatermarkClock.Templates return (content, 1); } /// <summary> /// 获取文件内容(带缓存,仅缓存成功读取的内容) /// </summary> private string GetFileContent(string filePath, int lineNumber) { var cacheKey = $"{filePath}:{lineNumber}"; // 检查缓存 if (_contentCache.TryGetValue(cacheKey, out var cachedContent)) return cachedContent; // 读取文件 var content = ReadFileLine(filePath, lineNumber); // 仅缓存成功读取的内容(不以 "[" 开头的错误信息) if (!content.StartsWith("[")) { _contentCache[cacheKey] = content; } return content; } /// <summary> /// 实际读取文件行 /// </summary> private string ReadFileLine(string filePath, int lineNumber) { try Loading @@ -71,6 +119,15 @@ namespace WatermarkClock.Templates } } /// <summary> /// 清除缓存(用于手动刷新) /// </summary> public void ClearCache() { _contentCache.Clear(); _parseCache.Clear(); } public IEnumerable<TemplateVariable> GetVariables() { yield return new TemplateVariable($"{{{_flag}文件路径}}", "读取文件第一行"); Loading Loading
src/WatermarkClock/Templates/FileReader.cs +60 −3 Original line number Diff line number Diff line Loading @@ -13,6 +13,12 @@ namespace WatermarkClock.Templates // 匹配 {*...} 整体内容 private readonly Regex _pattern = new Regex(@"\{\*([^}]+)\}", RegexOptions.Compiled); // 缓存:key = "filePath:lineNumber", value = 文件内容(仅缓存成功读取的内容) private readonly Dictionary<string, string> _contentCache = new Dictionary<string, string>(); // 缓存:key = 原始内容(如 "C:\path:1"),value = 解析后的 (path, line) private readonly Dictionary<string, (string path, int line)> _parseCache = new Dictionary<string, (string path, int line)>(); public string Replace(string input) { if (string.IsNullOrEmpty(input)) Loading @@ -23,8 +29,8 @@ namespace WatermarkClock.Templates return _pattern.Replace(input, match => { var content = match.Groups[1].Value; var (filePath, lineNumber) = ParsePathAndLine(content); return ReadFileLine(filePath, lineNumber); var (filePath, lineNumber) = GetParsedPathAndLine(content); return GetFileContent(filePath, lineNumber); }); } catch Loading @@ -33,6 +39,22 @@ namespace WatermarkClock.Templates } } /// <summary> /// 获取解析后的路径和行号(带缓存) /// </summary> private (string path, int line) GetParsedPathAndLine(string content) { if (_parseCache.TryGetValue(content, out var cached)) return cached; var result = ParsePathAndLine(content); _parseCache[content] = result; return result; } /// <summary> /// 解析路径和行号 /// </summary> private (string path, int line) ParsePathAndLine(string content) { // 从末尾查找 :数字 作为行号 Loading @@ -53,6 +75,32 @@ namespace WatermarkClock.Templates return (content, 1); } /// <summary> /// 获取文件内容(带缓存,仅缓存成功读取的内容) /// </summary> private string GetFileContent(string filePath, int lineNumber) { var cacheKey = $"{filePath}:{lineNumber}"; // 检查缓存 if (_contentCache.TryGetValue(cacheKey, out var cachedContent)) return cachedContent; // 读取文件 var content = ReadFileLine(filePath, lineNumber); // 仅缓存成功读取的内容(不以 "[" 开头的错误信息) if (!content.StartsWith("[")) { _contentCache[cacheKey] = content; } return content; } /// <summary> /// 实际读取文件行 /// </summary> private string ReadFileLine(string filePath, int lineNumber) { try Loading @@ -71,6 +119,15 @@ namespace WatermarkClock.Templates } } /// <summary> /// 清除缓存(用于手动刷新) /// </summary> public void ClearCache() { _contentCache.Clear(); _parseCache.Clear(); } public IEnumerable<TemplateVariable> GetVariables() { yield return new TemplateVariable($"{{{_flag}文件路径}}", "读取文件第一行"); Loading