Files
font-preview/FontPreview/FontCache.cs
T

90 lines
2.7 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;
namespace FontPreview
{
/// <summary>
/// 字体清单缓存:首次扫描后落盘,后续启动直接读缓存秒显,
/// 后台再按 文件路径/大小/修改时间 做增量对比,未变化的不重新解析。
/// </summary>
public class FontCache
{
public struct Stamp
{
public long Size;
public long Mtime;
}
public string RootDir;
public List<FontItem> Items = new List<FontItem>();
public Dictionary<string, Stamp> Stamps = new Dictionary<string, Stamp>(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 { }
}
}
}