Cache when reading embedded resources
Some checks are pending
release Linux / build (Release) (push) Waiting to run
release macOS / build (Release) (push) Waiting to run
release Windows desktop (Avalonia UI) / build (Release) (push) Waiting to run
release Windows / build (Release) (push) Waiting to run

This commit is contained in:
2dust 2025-01-31 16:02:29 +08:00
parent 331d11aee2
commit 4faa94b2a3
10 changed files with 94 additions and 83 deletions

View file

@ -0,0 +1,61 @@
using System.Collections.Concurrent;
using System.Reflection;
namespace ServiceLib.Common;
public static class EmbedUtils
{
private static readonly string _tag = "EmbedUtils";
private static readonly ConcurrentDictionary<string, string> _dicEmbedCache = new();
/// <summary>
/// Get embedded text resources
/// </summary>
/// <param name="res"></param>
/// <returns></returns>
public static string GetEmbedText(string res)
{
if (_dicEmbedCache.TryGetValue(res, out var value))
{
return value;
}
var result = string.Empty;
try
{
var assembly = Assembly.GetExecutingAssembly();
using var stream = assembly.GetManifestResourceStream(res);
ArgumentNullException.ThrowIfNull(stream);
using StreamReader reader = new(stream);
result = reader.ReadToEnd();
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
_dicEmbedCache.TryAdd(res, result);
return result;
}
/// <summary>
/// Get local storage resources
/// </summary>
/// <returns></returns>
public static string? LoadResource(string? res)
{
try
{
if (File.Exists(res))
{
return File.ReadAllText(res);
}
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
return null;
}
}

View file

@ -17,56 +17,6 @@ namespace ServiceLib.Common
{ {
private static readonly string _tag = "Utils"; private static readonly string _tag = "Utils";
#region
/// <summary>
/// 获取嵌入文本资源
/// </summary>
/// <param name="res"></param>
/// <returns></returns>
public static string GetEmbedText(string res)
{
var result = string.Empty;
try
{
var assembly = Assembly.GetExecutingAssembly();
using var stream = assembly.GetManifestResourceStream(res);
ArgumentNullException.ThrowIfNull(stream);
using StreamReader reader = new(stream);
result = reader.ReadToEnd();
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
return result;
}
/// <summary>
/// 取得存储资源
/// </summary>
/// <returns></returns>
public static string? LoadResource(string? res)
{
try
{
if (File.Exists(res))
{
return File.ReadAllText(res);
}
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
return null;
}
#endregion
#region #region
/// <summary> /// <summary>

View file

@ -142,7 +142,7 @@ namespace ServiceLib.Handler
{ {
try try
{ {
var linuxConfig = Utils.GetEmbedText(Global.LinuxAutostartConfig); var linuxConfig = EmbedUtils.GetEmbedText(Global.LinuxAutostartConfig);
if (linuxConfig.IsNotEmpty()) if (linuxConfig.IsNotEmpty())
{ {
linuxConfig = linuxConfig.Replace("$ExecPath$", Utils.GetExePath()); linuxConfig = linuxConfig.Replace("$ExecPath$", Utils.GetExePath());

View file

@ -21,7 +21,7 @@ namespace ServiceLib.Handler
public static Config? LoadConfig() public static Config? LoadConfig()
{ {
Config? config = null; Config? config = null;
var result = Utils.LoadResource(Utils.GetConfigPath(_configRes)); var result = EmbedUtils.LoadResource(Utils.GetConfigPath(_configRes));
if (Utils.IsNotEmpty(result)) if (Utils.IsNotEmpty(result))
{ {
config = JsonUtils.Deserialize<Config>(result); config = JsonUtils.Deserialize<Config>(result);
@ -1735,7 +1735,7 @@ namespace ServiceLib.Handler
Url = string.Empty, Url = string.Empty,
Sort = maxSort + 1, Sort = maxSort + 1,
}; };
await AddBatchRoutingRules(item2, Utils.GetEmbedText(Global.CustomRoutingFileName + "white")); await AddBatchRoutingRules(item2, EmbedUtils.GetEmbedText(Global.CustomRoutingFileName + "white"));
//Blacklist //Blacklist
var item3 = new RoutingItem() var item3 = new RoutingItem()
@ -1744,7 +1744,7 @@ namespace ServiceLib.Handler
Url = string.Empty, Url = string.Empty,
Sort = maxSort + 2, Sort = maxSort + 2,
}; };
await AddBatchRoutingRules(item3, Utils.GetEmbedText(Global.CustomRoutingFileName + "black")); await AddBatchRoutingRules(item3, EmbedUtils.GetEmbedText(Global.CustomRoutingFileName + "black"));
//Global //Global
var item1 = new RoutingItem() var item1 = new RoutingItem()
@ -1753,7 +1753,7 @@ namespace ServiceLib.Handler
Url = string.Empty, Url = string.Empty,
Sort = maxSort + 3, Sort = maxSort + 3,
}; };
await AddBatchRoutingRules(item1, Utils.GetEmbedText(Global.CustomRoutingFileName + "global")); await AddBatchRoutingRules(item1, EmbedUtils.GetEmbedText(Global.CustomRoutingFileName + "global"));
if (!blImportAdvancedRules) if (!blImportAdvancedRules)
{ {

View file

@ -35,7 +35,7 @@ namespace ServiceLib.Handler
var path = Path.Combine(_configPath, "pac.txt"); var path = Path.Combine(_configPath, "pac.txt");
if (!File.Exists(path)) if (!File.Exists(path))
{ {
var pac = Utils.GetEmbedText(Global.PacFileName); var pac = EmbedUtils.GetEmbedText(Global.PacFileName);
await File.AppendAllTextAsync(path, pac); await File.AppendAllTextAsync(path, pac);
} }

View file

@ -116,7 +116,7 @@ namespace ServiceLib.Services.CoreConfig
//enable tun mode //enable tun mode
if (_config.TunModeItem.EnableTun) if (_config.TunModeItem.EnableTun)
{ {
string tun = Utils.GetEmbedText(Global.ClashTunYaml); string tun = EmbedUtils.GetEmbedText(Global.ClashTunYaml);
if (Utils.IsNotEmpty(tun)) if (Utils.IsNotEmpty(tun))
{ {
var tunContent = YamlUtils.FromYaml<Dictionary<string, object>>(tun); var tunContent = YamlUtils.FromYaml<Dictionary<string, object>>(tun);

View file

@ -35,7 +35,7 @@ namespace ServiceLib.Services.CoreConfig
ret.Msg = ResUI.InitialConfiguration; ret.Msg = ResUI.InitialConfiguration;
string result = Utils.GetEmbedText(Global.SingboxSampleClient); string result = EmbedUtils.GetEmbedText(Global.SingboxSampleClient);
if (Utils.IsNullOrEmpty(result)) if (Utils.IsNullOrEmpty(result))
{ {
ret.Msg = ResUI.FailedGetDefaultConfiguration; ret.Msg = ResUI.FailedGetDefaultConfiguration;
@ -91,8 +91,8 @@ namespace ServiceLib.Services.CoreConfig
ret.Msg = ResUI.InitialConfiguration; ret.Msg = ResUI.InitialConfiguration;
var result = Utils.GetEmbedText(Global.SingboxSampleClient); var result = EmbedUtils.GetEmbedText(Global.SingboxSampleClient);
var txtOutbound = Utils.GetEmbedText(Global.SingboxSampleOutbound); var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty()) if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty())
{ {
ret.Msg = ResUI.FailedGetDefaultConfiguration; ret.Msg = ResUI.FailedGetDefaultConfiguration;
@ -255,8 +255,8 @@ namespace ServiceLib.Services.CoreConfig
ret.Msg = ResUI.InitialConfiguration; ret.Msg = ResUI.InitialConfiguration;
string result = Utils.GetEmbedText(Global.SingboxSampleClient); string result = EmbedUtils.GetEmbedText(Global.SingboxSampleClient);
string txtOutbound = Utils.GetEmbedText(Global.SingboxSampleOutbound); string txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty()) if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty())
{ {
ret.Msg = ResUI.FailedGetDefaultConfiguration; ret.Msg = ResUI.FailedGetDefaultConfiguration;
@ -546,7 +546,7 @@ namespace ServiceLib.Services.CoreConfig
_config.TunModeItem.Stack = Global.TunStacks.First(); _config.TunModeItem.Stack = Global.TunStacks.First();
} }
var tunInbound = JsonUtils.Deserialize<Inbound4Sbox>(Utils.GetEmbedText(Global.TunSingboxInboundFileName)) ?? new Inbound4Sbox { }; var tunInbound = JsonUtils.Deserialize<Inbound4Sbox>(EmbedUtils.GetEmbedText(Global.TunSingboxInboundFileName)) ?? new Inbound4Sbox { };
tunInbound.interface_name = Utils.IsOSX() ? $"utun{new Random().Next(99)}" : "singbox_tun"; tunInbound.interface_name = Utils.IsOSX() ? $"utun{new Random().Next(99)}" : "singbox_tun";
tunInbound.mtu = _config.TunModeItem.Mtu; tunInbound.mtu = _config.TunModeItem.Mtu;
tunInbound.strict_route = _config.TunModeItem.StrictRoute; tunInbound.strict_route = _config.TunModeItem.StrictRoute;
@ -867,7 +867,7 @@ namespace ServiceLib.Services.CoreConfig
//current proxy //current proxy
var outbound = singboxConfig.outbounds.First(); var outbound = singboxConfig.outbounds.First();
var txtOutbound = Utils.GetEmbedText(Global.SingboxSampleOutbound); var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
//Previous proxy //Previous proxy
var prevNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.PrevProfile); var prevNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.PrevProfile);
@ -934,7 +934,7 @@ namespace ServiceLib.Services.CoreConfig
{ {
singboxConfig.route.auto_detect_interface = true; singboxConfig.route.auto_detect_interface = true;
var tunRules = JsonUtils.Deserialize<List<Rule4Sbox>>(Utils.GetEmbedText(Global.TunSingboxRulesFileName)); var tunRules = JsonUtils.Deserialize<List<Rule4Sbox>>(EmbedUtils.GetEmbedText(Global.TunSingboxRulesFileName));
if (tunRules != null) if (tunRules != null)
{ {
singboxConfig.route.rules.AddRange(tunRules); singboxConfig.route.rules.AddRange(tunRules);
@ -1171,11 +1171,11 @@ namespace ServiceLib.Services.CoreConfig
var strDNS = string.Empty; var strDNS = string.Empty;
if (_config.TunModeItem.EnableTun) if (_config.TunModeItem.EnableTun)
{ {
strDNS = Utils.IsNullOrEmpty(item?.TunDNS) ? Utils.GetEmbedText(Global.TunSingboxDNSFileName) : item?.TunDNS; strDNS = Utils.IsNullOrEmpty(item?.TunDNS) ? EmbedUtils.GetEmbedText(Global.TunSingboxDNSFileName) : item?.TunDNS;
} }
else else
{ {
strDNS = Utils.IsNullOrEmpty(item?.NormalDNS) ? Utils.GetEmbedText(Global.DNSSingboxNormalFileName) : item?.NormalDNS; strDNS = Utils.IsNullOrEmpty(item?.NormalDNS) ? EmbedUtils.GetEmbedText(Global.DNSSingboxNormalFileName) : item?.NormalDNS;
} }
var dns4Sbox = JsonUtils.Deserialize<Dns4Sbox>(strDNS); var dns4Sbox = JsonUtils.Deserialize<Dns4Sbox>(strDNS);
@ -1326,7 +1326,7 @@ namespace ServiceLib.Services.CoreConfig
var routing = await ConfigHandler.GetDefaultRouting(_config); var routing = await ConfigHandler.GetDefaultRouting(_config);
if (Utils.IsNotEmpty(routing.CustomRulesetPath4Singbox)) if (Utils.IsNotEmpty(routing.CustomRulesetPath4Singbox))
{ {
var result = Utils.LoadResource(routing.CustomRulesetPath4Singbox); var result = EmbedUtils.LoadResource(routing.CustomRulesetPath4Singbox);
if (Utils.IsNotEmpty(result)) if (Utils.IsNotEmpty(result))
{ {
customRulesets = (JsonUtils.Deserialize<List<Ruleset4Sbox>>(result) ?? []) customRulesets = (JsonUtils.Deserialize<List<Ruleset4Sbox>>(result) ?? [])

View file

@ -1,4 +1,4 @@
using System.Net; using System.Net;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Text.Json.Nodes; using System.Text.Json.Nodes;
@ -36,7 +36,7 @@ namespace ServiceLib.Services.CoreConfig
ret.Msg = ResUI.InitialConfiguration; ret.Msg = ResUI.InitialConfiguration;
var result = Utils.GetEmbedText(Global.V2raySampleClient); var result = EmbedUtils.GetEmbedText(Global.V2raySampleClient);
if (Utils.IsNullOrEmpty(result)) if (Utils.IsNullOrEmpty(result))
{ {
ret.Msg = ResUI.FailedGetDefaultConfiguration; ret.Msg = ResUI.FailedGetDefaultConfiguration;
@ -91,8 +91,8 @@ namespace ServiceLib.Services.CoreConfig
ret.Msg = ResUI.InitialConfiguration; ret.Msg = ResUI.InitialConfiguration;
string result = Utils.GetEmbedText(Global.V2raySampleClient); string result = EmbedUtils.GetEmbedText(Global.V2raySampleClient);
string txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound); string txtOutbound = EmbedUtils.GetEmbedText(Global.V2raySampleOutbound);
if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty()) if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty())
{ {
ret.Msg = ResUI.FailedGetDefaultConfiguration; ret.Msg = ResUI.FailedGetDefaultConfiguration;
@ -214,8 +214,8 @@ namespace ServiceLib.Services.CoreConfig
ret.Msg = ResUI.InitialConfiguration; ret.Msg = ResUI.InitialConfiguration;
var result = Utils.GetEmbedText(Global.V2raySampleClient); var result = EmbedUtils.GetEmbedText(Global.V2raySampleClient);
var txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound); var txtOutbound = EmbedUtils.GetEmbedText(Global.V2raySampleOutbound);
if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty()) if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty())
{ {
ret.Msg = ResUI.FailedGetDefaultConfiguration; ret.Msg = ResUI.FailedGetDefaultConfiguration;
@ -428,7 +428,7 @@ namespace ServiceLib.Services.CoreConfig
private Inbounds4Ray GetInbound(InItem inItem, EInboundProtocol protocol, bool bSocks) private Inbounds4Ray GetInbound(InItem inItem, EInboundProtocol protocol, bool bSocks)
{ {
string result = Utils.GetEmbedText(Global.V2raySampleInbound); string result = EmbedUtils.GetEmbedText(Global.V2raySampleInbound);
if (Utils.IsNullOrEmpty(result)) if (Utils.IsNullOrEmpty(result))
{ {
return new(); return new();
@ -992,7 +992,7 @@ namespace ServiceLib.Services.CoreConfig
}; };
//request Host //request Host
string request = Utils.GetEmbedText(Global.V2raySampleHttpRequestFileName); string request = EmbedUtils.GetEmbedText(Global.V2raySampleHttpRequestFileName);
string[] arrHost = host.Split(','); string[] arrHost = host.Split(',');
string host2 = string.Join(",".AppendQuotes(), arrHost); string host2 = string.Join(",".AppendQuotes(), arrHost);
request = request.Replace("$requestHost$", $"{host2.AppendQuotes()}"); request = request.Replace("$requestHost$", $"{host2.AppendQuotes()}");
@ -1028,7 +1028,7 @@ namespace ServiceLib.Services.CoreConfig
var domainStrategy4Freedom = item?.DomainStrategy4Freedom; var domainStrategy4Freedom = item?.DomainStrategy4Freedom;
if (Utils.IsNullOrEmpty(normalDNS)) if (Utils.IsNullOrEmpty(normalDNS))
{ {
normalDNS = Utils.GetEmbedText(Global.DNSV2rayNormalFileName); normalDNS = EmbedUtils.GetEmbedText(Global.DNSV2rayNormalFileName);
} }
//Outbound Freedom domainStrategy //Outbound Freedom domainStrategy
@ -1196,7 +1196,7 @@ namespace ServiceLib.Services.CoreConfig
//current proxy //current proxy
var outbound = v2rayConfig.outbounds.First(); var outbound = v2rayConfig.outbounds.First();
var txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound); var txtOutbound = EmbedUtils.GetEmbedText(Global.V2raySampleOutbound);
//Previous proxy //Previous proxy
var prevNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.PrevProfile); var prevNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.PrevProfile);
@ -1247,4 +1247,4 @@ namespace ServiceLib.Services.CoreConfig
#endregion private gen function #endregion private gen function
} }
} }

View file

@ -31,14 +31,14 @@ namespace ServiceLib.ViewModels
ImportDefConfig4V2rayCmd = ReactiveCommand.CreateFromTask(async () => ImportDefConfig4V2rayCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
normalDNS = Utils.GetEmbedText(Global.DNSV2rayNormalFileName); normalDNS = EmbedUtils.GetEmbedText(Global.DNSV2rayNormalFileName);
await Task.CompletedTask; await Task.CompletedTask;
}); });
ImportDefConfig4SingboxCmd = ReactiveCommand.CreateFromTask(async () => ImportDefConfig4SingboxCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName); normalDNS2 = EmbedUtils.GetEmbedText(Global.DNSSingboxNormalFileName);
tunDNS2 = Utils.GetEmbedText(Global.TunSingboxDNSFileName); tunDNS2 = EmbedUtils.GetEmbedText(Global.TunSingboxDNSFileName);
await Task.CompletedTask; await Task.CompletedTask;
}); });

View file

@ -257,7 +257,7 @@ namespace ServiceLib.ViewModels
return; return;
} }
var result = Utils.LoadResource(fileName); var result = EmbedUtils.LoadResource(fileName);
if (Utils.IsNullOrEmpty(result)) if (Utils.IsNullOrEmpty(result))
{ {
return; return;