Skip to content

编码处理流程

本文档描述 Apq.Cfg 库在读取和写入配置文件时的完整编码处理流程。

概述

Apq.Cfg 提供了灵活的编码处理机制,支持:

  • 自动检测文件编码(BOM 优先,UTF.Unknown 库辅助)
  • 自定义编码映射(完整路径、通配符、正则表达式)
  • 多种写入策略(UTF-8 无 BOM、UTF-8 带 BOM、保持原编码、指定编码)

核心类

类名职责
EncodingDetector编码检测器,管理映射规则和缓存
EncodingMappingConfig编码映射配置,存储读取/写入规则
EncodingMappingRule单条映射规则
EncodingOptions单个配置源的编码选项
FileCfgSourceBase文件配置源基类,调用编码检测和写入

读取流程

流程图

读取文件


┌─────────────────────────────────────┐
│ 1. 检查 EncodingOptions.ReadStrategy │
│    是否为 Specified?                │
└─────────────────────────────────────┘
    │ 是                    │ 否
    ▼                       ▼
┌─────────────┐    ┌─────────────────────────┐
│ 返回指定编码 │    │ 2. 检查读取映射配置      │
└─────────────┘    │    (MappingConfig)       │
                   └─────────────────────────┘
                       │ 匹配              │ 不匹配
                       ▼                   │
               ┌─────────────────────┐     │
               │ 3. 验证映射编码      │     │
               │    能否正确读取文件  │     │
               └─────────────────────┘     │
                   │ 成功        │ 失败    │
                   ▼             └────┬────┘
           ┌─────────────┐            │
           │ 返回映射编码 │            │
           └─────────────┘            │

                          ┌─────────────────────┐
                          │ 4. 检查缓存          │
                          │    (如果启用)        │
                          └─────────────────────┘
                              │ 命中        │ 未命中
                              ▼             ▼
                      ┌─────────────┐  ┌─────────────────┐
                      │ 返回缓存结果 │  │ 5. BOM 检测      │
                      └─────────────┘  └─────────────────┘
                                           │ 有 BOM    │ 无 BOM
                                           ▼           ▼
                                   ┌───────────┐  ┌─────────────────┐
                                   │ 返回 BOM  │  │ 6. UTF.Unknown  │
                                   │ 对应编码  │  │    库检测       │
                                   └───────────┘  └─────────────────┘
                                                      │ 置信度 ≥ 阈值  │ < 阈值
                                                      ▼                ▼
                                              ┌─────────────┐  ┌─────────────┐
                                              │ 返回检测编码 │  │ 返回回退编码 │
                                              └─────────────┘  │ (默认 UTF-8) │
                                                               └─────────────┘

代码路径

  1. 入口: FileCfgSourceBase.DetectEncodingEnhanced(path)
  2. 调用: EncodingDetector.Detect(path, options)
  3. 返回: EncodingOptions.GetReadEncoding(detectedEncoding)

映射规则优先级

映射规则按优先级降序排列,返回第一个匹配的规则:

匹配类型默认优先级说明
ExactPath100完整路径精确匹配
Wildcard0通配符匹配
Regex0正则表达式匹配
内置 PowerShell-100*.ps1, *.psm1, *.psd1

映射编码验证

当读取映射匹配成功后,系统会验证该编码是否能正确读取文件:

  1. 验证方式: 使用 DecoderFallback.ExceptionFallback 尝试解码文件前 4KB
  2. 验证成功: 使用映射编码
  3. 验证失败: 回退到自动检测流程(BOM 检测 → UTF.Unknown → 回退编码)

这确保了即使配置了错误的编码映射,系统也能自动回退到正确的编码检测。

BOM 检测

支持的 BOM 类型:

BOM 字节编码
EF BB BFUTF-8
FF FEUTF-16 LE
FE FFUTF-16 BE
FF FE 00 00UTF-32 LE
00 00 FE FFUTF-32 BE

写入流程

流程图

写入文件


┌─────────────────────────────────────────┐
│ 1. 检查 EncodingOptions.WriteStrategy   │
└─────────────────────────────────────────┘

    ├─── Utf8NoBom ──────► 返回 UTF-8 无 BOM

    ├─── Utf8WithBom ────► 返回 UTF-8 带 BOM

    ├─── Specified ──────► 返回 EncodingOptions.WriteEncoding

    └─── Preserve ───────┐

              ┌─────────────────────────┐
              │ 2. 检查已检测的原编码    │
              │    (_detectedEncoding)  │
              └─────────────────────────┘
                  │ 有                │ 无
                  ▼                   ▼
          ┌─────────────┐    ┌─────────────────────┐
          │ 返回原编码   │    │ 3. 检查写入映射配置  │
          └─────────────┘    │    (MappingConfig)   │
                             └─────────────────────┘
                                 │ 匹配         │ 不匹配
                                 ▼              ▼
                         ┌─────────────┐  ┌─────────────────┐
                         │ 返回映射编码 │  │ 返回 UTF-8 无 BOM │
                         └─────────────┘  │ (默认)           │
                                          └─────────────────┘

代码路径

  1. 入口: FileCfgSourceBase.GetWriteEncoding()
  2. 策略判断: 根据 EncodingOptions.WriteStrategy 分支
  3. 映射查询: EncodingDetector.GetWriteEncoding(path)

写入策略

策略说明
Utf8NoBom统一转换为 UTF-8 无 BOM(默认)
Utf8WithBom统一转换为 UTF-8 带 BOM
Preserve保持原文件编码
Specified使用指定的编码

配置示例

基本用法

csharp
// 默认配置:自动检测读取,UTF-8 无 BOM 写入
var cfg = new CfgBuilder()
    .AddJson("config.json", level: 0, writeable: true)
    .Build();

指定写入编码

csharp
// PowerShell 文件使用 UTF-8 带 BOM
var cfg = new CfgBuilder()
    .AddJson("config.json", level: 0, writeable: true,
        encoding: EncodingOptions.PowerShell)
    .Build();

保持原编码

csharp
var options = new EncodingOptions
{
    WriteStrategy = EncodingWriteStrategy.Preserve
};

var cfg = new CfgBuilder()
    .AddJson("legacy.json", level: 0, writeable: true, encoding: options)
    .Build();

全局编码映射

csharp
var cfg = new CfgBuilder()
    // 特定文件使用 GB2312 读取
    .AddReadEncodingMapping(@"C:\legacy\old.ini", Encoding.GetEncoding("GB2312"))

    // 所有 PS1 文件写入时使用 UTF-8 BOM
    .AddWriteEncodingMappingWildcard("*.ps1", new UTF8Encoding(true))

    // 正则匹配
    .AddWriteEncodingMappingRegex(@"logs[/\\].*\.log$", Encoding.Unicode)

    .AddJson("config.json", level: 0, writeable: true)
    .Build();

高级配置

csharp
var cfg = new CfgBuilder()
    .ConfigureEncodingMapping(config =>
    {
        // 添加多条规则
        config.AddReadMapping("*.xml", EncodingMappingType.Wildcard,
            Encoding.UTF8, priority: 50);
        config.AddWriteMapping("**/*.txt", EncodingMappingType.Wildcard,
            new UTF8Encoding(true), priority: 10);

        // 清除默认规则
        config.ClearWriteMappings();
    })
    .WithEncodingConfidenceThreshold(0.8f)  // 提高检测置信度阈值
    .WithEncodingDetectionLogging(result =>  // 启用日志
    {
        Console.WriteLine($"检测到编码: {result}");
    })
    .AddJson("config.json", level: 0, writeable: true)
    .Build();

通配符语法

符号含义示例
*匹配任意字符(不含路径分隔符)*.json 匹配 config.json
**匹配任意字符(含路径分隔符)**/*.txt 匹配 a/b/c.txt
?匹配单个字符config?.json 匹配 config1.json

缓存机制

编码检测结果会被缓存以提高性能:

  • 缓存键: 文件完整路径
  • 失效条件: 文件修改时间变化
  • 手动清除: EncodingDetector.ClearCache()InvalidateCache(path)
csharp
// 禁用缓存
var options = new EncodingOptions { EnableCache = false };

// 手动清除缓存
FileCfgSourceBase.EncodingDetector.ClearCache();

内置默认映射

EncodingDetector 构造时自动添加以下写入映射:

模式编码优先级
*.ps1UTF-8 BOM-100
*.psm1UTF-8 BOM-100
*.psd1UTF-8 BOM-100

这些默认映射优先级最低,可被用户配置覆盖。

环境变量

变量名说明默认值
APQ_CFG_ENCODING_CONFIDENCE编码检测置信度阈值0.6

API 参考

CfgBuilder 方法

方法说明
AddReadEncodingMapping(path, encoding, priority)添加读取映射(完整路径)
AddReadEncodingMappingWildcard(pattern, encoding, priority)添加读取映射(通配符)
AddReadEncodingMappingRegex(pattern, encoding, priority)添加读取映射(正则)
AddWriteEncodingMapping(path, encoding, priority)添加写入映射(完整路径)
AddWriteEncodingMappingWildcard(pattern, encoding, priority)添加写入映射(通配符)
AddWriteEncodingMappingRegex(pattern, encoding, priority)添加写入映射(正则)
ConfigureEncodingMapping(Action<EncodingMappingConfig>)高级配置
WithEncodingConfidenceThreshold(float)设置置信度阈值
WithEncodingDetectionLogging(Action<EncodingDetectionResult>)启用检测日志

EncodingOptions 属性

属性类型默认值说明
ReadStrategyEncodingReadStrategyAutoDetect读取策略
WriteStrategyEncodingWriteStrategyUtf8NoBom写入策略
ReadEncodingEncoding?null指定读取编码
WriteEncodingEncoding?null指定写入编码
FallbackEncodingEncodingUTF8回退编码
ConfidenceThresholdfloat0.6置信度阈值
EnableCachebooltrue启用缓存
EnableLoggingboolfalse启用日志

预定义 EncodingOptions

名称说明
EncodingOptions.Default默认配置
EncodingOptions.PowerShellPowerShell 脚本配置(UTF-8 BOM)

下一步

基于 MIT 许可发布