关于本文
本文是通过利用生成式 AI 的自动化生成流程创建的。我们确认了 .NET 的 Encoding API,将虚拟固定长记录作为字节序列进行观察,并将其整理为用于调查业务文件中项目偏移或字符编码不匹配的形式。验证状态:📘 已确认 .NET 官方规范・未在实机上验证
在固定长文件中,空格也是数据。不仅查看屏幕上的字符串,还要查看字节位置,这样就能明确“从哪里到哪里是一个项目”。
这种思路有助于调查老旧核心系统、全银系统等固定宽度数据,以及与外部承包商的协作文件中“看着完全正确却导入报错”的原因。
本次的成功条件
如果能将 1 条记录转换为 ASCII 字节序列,并带有位置信息地确认字符、空格和项目边界,即视为成功。
首先尝试
$record = '001PANDA 025'
$bytes = [Text.Encoding]::ASCII.GetBytes($record)
0..($bytes.Length-1) | ForEach-Object {
'{0:D2}: {1:X2} {2}' -f $_,$bytes[$_],[char]$bytes[$_]
}
查看这里
空格20是作为存在的。它并不是在视觉上消失了,而是填充项目宽度的字节。
例如,假设该虚拟记录符合以下规范。
| 字节位置 | 项目 | 宽度 |
|---|---|---|
| 0-2 | 代码 | 3 字节 |
| 3-12 | 名称 | 10 字节 |
| 13-15 | 数量 | 3 字节 |
PANDA后面的空格也是用于填满名称栏 10 字节的数据。
尝试按项目单位分割
固定长数据如果按字节位置分割,结构就会显现出来。
$code = [Text.Encoding]::ASCII.GetString($bytes, 0, 3)
$name = [Text.Encoding]::ASCII.GetString($bytes, 3, 10)
$qty = [Text.Encoding]::ASCII.GetString($bytes, 13, 3)
[pscustomobject]@{
Code = $code
Name = $name.TrimEnd()
Qty = $qty
}
比起浏览整个字符串,它能够与规范说明书中“3 字节、10 字节、3 字节”的定义直接进行核对。
尝试更改一处
PANDA将パンダ更改为并将 Encoding 设置为 UTF-8。
$record = '001パンダ 025' $bytes = [Text.Encoding]::UTF8.GetBytes($record) "文字数 = $($record.Length)" "byte数 = $($bytes.Length)"
字符数和字节数将不再一致。
这里可以明白的是,固定长规范中的“10 个字符”和“10 字节”并不相同这一点。
为什么会这样
文件归根结底是字节序列。字符编码决定了将字符转换为哪种字节序列。
ASCII 的英数字母基本上是 1 个字符对应 1 个字节,因此字符数和字节数很容易一致。另一方面,如果在 UTF-8 中使用日语,则 1 个字符会变成多个字节,因此如果仅凭字符数来管理固定宽度,边界有时会发生偏移。
graph LR A[文字列] --> B[Encoding] B --> C[byte列] C --> D[固定位置で項目分割]
试着故意破坏它
假设固定长规范为“名称 10 字节”,但仅凭字符数输入了 10 个 UTF-8 日语字符。
在这种情况下,名称栏可能会超过 10 字节,并侵入后面数量栏的起始位置。
也就是说,
コード | 名称 | 数量 001 | 10byte固定 | 025
明明是这样的规范,但如果名称实际延伸到 13 字节、15 字节……其后面的项目位置就会全部错位。
这种类型的错误仅通过在屏幕上查看字符串很难找出原因。
深入一步:检查字节数而不是字符数
作为业务检查,可以预先检查各个项目的字节数。
$name = 'パンダ'
$encoding = [Text.Encoding]::UTF8
$byteCount = $encoding.GetByteCount($name)
[pscustomobject]@{
Value = $name
CharCount = $name.Length
ByteCount = $byteCount
LimitBytes = 10
Fits = ($byteCount -le 10)
}
Fits通过查看,可以机械性地确认“这个值是否可以放入 10 字节栏中”。
可以在文职与业务中的哪些地方使用
1. 核心系统上传错误的调查
在上传固定长文件而非 CSV 的业务中,
仅特定行报错
只有输入了日语的行失败
数量或金额错位到相邻的项目
如果出现诸如此类的现象,将目标行匿名化后查看字节位置即可缩小原因范围。
2. Excel 制作的数据在交付前的检查
在文职人员使用 Excel 输入并最终转换为固定长文本的业务中,有时仅凭单元格的LEN无法判断字节限制。
可以在 PowerShell 端检查字节数,
是否在规定字节以内
是否混入了全角字符
是否需要末尾空格
并将其发展为用于确认的简易检查工具。
3. 与供应商确认规范
仅写着“名称 10 位”的规范书有时是不够充分的。
应该确认的是,
是 10 个字符还是 10 字节
Encoding 是什么
填充是空格
0还是是左对齐还是右对齐
换行符是否包含在记录长度中
这些内容。
仅仅能够询问这 5 点,就能减少验收测试前的问题。
4. 确认无法目视的空格
当出现“在 Excel 中看明明一样,却只有一方报错”的情况时,半角空格、全角空格、NULL、换行等难以察觉的差异有时会成为原因。
十六进制显示是用于将这些转换为可见值的工具。
如果在工作中应用
在调查全银系统或老旧协作文件时,确认规范书的 offset、encoding、padding 以及是否有换行符,不使用实际数据,而是通过匿名化样本进行解析。
首先仅通过 1 条记录确认结构,然后再扩展到全量检查是比较安全的做法。切勿突然修改生产环境文件,请从只读检查开始。
Microsoft Encoding.GetBytes: https://learn.microsoft.com/dotnet/api/system.text.encoding.getbytes
Microsoft Encoding.GetByteCount: https://learn.microsoft.com/dotnet/api/system.text.encoding.getbytecount
