using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Windows.Forms; namespace FontPreview { /// /// 字体清单缓存:首次扫描后落盘,后续启动直接读缓存秒显, /// 后台再按 文件路径/大小/修改时间 做增量对比,未变化的不重新解析。 /// public class FontCache { public struct Stamp { public long Size; public long Mtime; } public string RootDir; public List Items = new List(); public Dictionary Stamps = new Dictionary(StringComparer.OrdinalIgnoreCase); private static string CachePath => Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "fontcache.txt"); public static bool TryLoad(string rootDir, out FontCache cache) { cache = null; try { if (!File.Exists(CachePath)) return false; string[] lines = File.ReadAllLines(CachePath, Encoding.UTF8); if (lines.Length < 2 || lines[0] != "#FontCache v1") return false; string rd = null; for (int i = 0; i < lines.Length; i++) { if (lines[i].StartsWith("rootdir=")) { rd = lines[i].Substring(8).Trim(); break; } } if (rd == null || !string.Equals(rd, rootDir.Trim(), StringComparison.OrdinalIgnoreCase)) return false; FontCache c = new FontCache(); c.RootDir = rootDir; for (int i = 0; i < lines.Length; i++) { string l = lines[i]; if (string.IsNullOrEmpty(l) || l[0] == '#' || l.StartsWith("rootdir=")) continue; string[] p = l.Split('\t'); if (p.Length < 6) continue; FontItem it = new FontItem { Cat = p[0], Path = p[1], Name = p[2], DisplayName = p[3] }; c.Items.Add(it); long size, mt; if (long.TryParse(p[4], out size) && long.TryParse(p[5], out mt)) { c.Stamps[it.Path] = new Stamp { Size = size, Mtime = mt }; } } if (c.Items.Count == 0) return false; cache = c; return true; } catch { return false; } } public static void Save(FontCache c) { try { StringBuilder sb = new StringBuilder(); sb.AppendLine("#FontCache v1"); sb.AppendLine("rootdir=" + c.RootDir); foreach (FontItem it in c.Items) { Stamp st; c.Stamps.TryGetValue(it.Path, out st); string dn = (it.DisplayName ?? "").Replace("\t", " "); sb.Append(it.Cat).Append('\t').Append(it.Path).Append('\t') .Append(it.Name).Append('\t').Append(dn).Append('\t') .Append(st.Size).Append('\t').Append(st.Mtime).Append('\n'); } string tmp = CachePath + ".tmp"; File.WriteAllText(tmp, sb.ToString(), new UTF8Encoding(false)); if (File.Exists(CachePath)) { File.Copy(tmp, CachePath, true); File.Delete(tmp); } else { File.Move(tmp, CachePath); } } catch { } } } }