123 lines
4.0 KiB
Markdown
123 lines
4.0 KiB
Markdown
|
|
# 文件名解析器
|
|||
|
|
|
|||
|
|
> 所属模块:[解析器设计](./概览.md)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. 文件名格式
|
|||
|
|
|
|||
|
|
**格式约定**:`TX面板-TX硬件-TX软件-RX类型-测试目的-年月日-测试次数.log`
|
|||
|
|
|
|||
|
|
**分隔符**:支持 `-`(短横线)和 `_`(下划线)两种分隔符,文件名解析时将同时拆分这两种字符。
|
|||
|
|
|
|||
|
|
> ⚠️ **注意**:字段值内部不应包含分隔符字符。例如,若 TX面板值为 `single-mold`,解析时会拆分为 `single` 和 `mold` 两个字段,导致解析失败。请确保字段值本身不含 `-` 或 `_`。
|
|||
|
|
|
|||
|
|
**示例**:
|
|||
|
|
- 标准:`singleMold-v1.0-hex2_1-iPhone15-compatibility-20260702-1.log`(字段值无分隔符)
|
|||
|
|
- 避免:`single-mold-v1.0-hex2.1-iPhone15-兼容性测试-20260702-1.log`(`single-mold` 会拆分)
|
|||
|
|
|
|||
|
|
**位置说明**:表格中的"位置"采用 1-based 索引(从 1 开始计数),与代码中的 0-based 数组索引对应。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. 字段映射
|
|||
|
|
|
|||
|
|
| 位置 | 字段 | 对应维度表 | 示例值 |
|
|||
|
|
|------|------|------------|--------|
|
|||
|
|
| 1 | TxPanel | tx_panel.name | single-mold |
|
|||
|
|
| 2 | TxHardware | tx_hardware.version | v1.0 |
|
|||
|
|
| 3 | TxSoftware | tx_software.version | hex2.1 |
|
|||
|
|
| 4 | RxType | rx_type.name | iPhone15 |
|
|||
|
|
| 5 | TestPurpose | test_scenario.test_purpose | 兼容性测试 |
|
|||
|
|
| 6 | TestDate | test_scenario.test_date | 20260702 |
|
|||
|
|
| 7 | TestSequence | test_scenario.test_sequence | 1 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. 解析器实现
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// Parsers/FileNameParser.cs
|
|||
|
|
using System.Globalization;
|
|||
|
|
using WCTDataMiner.Services;
|
|||
|
|
|
|||
|
|
namespace WCTDataMiner.Parsers;
|
|||
|
|
|
|||
|
|
public class FileNameParser
|
|||
|
|
{
|
|||
|
|
private static readonly char[] Separators = { '-', '_' };
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 解析日志文件名,提取场景信息
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="fileName">文件名(不含路径)</param>
|
|||
|
|
/// <returns>场景信息,若格式不匹配返回 null</returns>
|
|||
|
|
public ScenarioInfo? Parse(string fileName)
|
|||
|
|
{
|
|||
|
|
// 移除 .log 扩展名
|
|||
|
|
var nameWithoutExt = Path.GetFileNameWithoutExtension(fileName);
|
|||
|
|
if (string.IsNullOrEmpty(nameWithoutExt))
|
|||
|
|
return null;
|
|||
|
|
|
|||
|
|
var parts = nameWithoutExt.Split(Separators);
|
|||
|
|
if (parts.Length < 7)
|
|||
|
|
return null;
|
|||
|
|
|
|||
|
|
// 解析日期
|
|||
|
|
if (!TryParseDate(parts[5], out var testDate))
|
|||
|
|
return null;
|
|||
|
|
|
|||
|
|
// 解析测试序号
|
|||
|
|
if (!int.TryParse(parts[6], out var testSequence))
|
|||
|
|
testSequence = 1;
|
|||
|
|
|
|||
|
|
return new ScenarioInfo(
|
|||
|
|
TxPanel: parts[0],
|
|||
|
|
TxHardware: parts[1],
|
|||
|
|
TxSoftware: parts[2],
|
|||
|
|
RxType: parts[3],
|
|||
|
|
TestPurpose: parts.Length > 4 ? parts[4] : null,
|
|||
|
|
TestDate: testDate,
|
|||
|
|
TestSequence: testSequence
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static bool TryParseDate(string dateStr, out DateOnly date)
|
|||
|
|
{
|
|||
|
|
// 支持多种日期格式
|
|||
|
|
var formats = new[] { "yyyyMMdd", "yyyy-MM-dd", "yyMMdd" };
|
|||
|
|
return DateOnly.TryParseExact(dateStr, formats, CultureInfo.InvariantCulture, DateTimeStyles.None, out date);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. 容错处理
|
|||
|
|
|
|||
|
|
| 场景 | 处理方式 |
|
|||
|
|
|------|----------|
|
|||
|
|
| 文件名为空或 null | 返回 null,ParseService 记录错误日志 |
|
|||
|
|
| 文件名仅含扩展名(如 `.log`) | 返回 null |
|
|||
|
|
| 文件名少于 7 个字段 | 返回 null,缺少必要字段 |
|
|||
|
|
| 日期格式不匹配 | 返回 null,无法解析 test_date |
|
|||
|
|
| 测试序号解析失败 | 使用默认值 1 |
|
|||
|
|
| 文件名扩展名无效(非 `.log`) | 仍会解析,仅去除扩展名后尝试 |
|
|||
|
|
|
|||
|
|
> **说明**:由于解析器要求 `parts.Length >= 7` 才会成功返回,"测试目的缺失"不会单独发生——当字段不足时整体解析失败。若需支持可选字段,需调整解析逻辑。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. 使用示例
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// 在 ParseService 中使用
|
|||
|
|
var fileNameParser = new FileNameParser();
|
|||
|
|
var scenarioInfo = fileNameParser.Parse("single-mold-v1.0-hex2.1-iPhone15-兼容性测试-20260702-1.log");
|
|||
|
|
|
|||
|
|
if (scenarioInfo != null)
|
|||
|
|
{
|
|||
|
|
var scenario = await scenarioService.GetOrCreateScenarioAsync(scenarioInfo);
|
|||
|
|
// 继续解析文件内容...
|
|||
|
|
}
|
|||
|
|
```
|