C# Git LFS指针文件 C#如何解析Git大文件存储的指针文件

4次阅读

git lfs指针文件是纯文本,格式为固定键值对,含version、oid和size行;c#需按行解析并校验version合法性,用trimstart()处理bom与空格,避免split(‘:’)误切。

C# Git LFS指针文件 C#如何解析Git大文件存储的指针文件

Git LFS指针文件长什么样

Git LFS不真正存储大文件,而是用纯文本指针文件代替——你看到的 .gitattributes 里匹配的文件(比如 *.psd),在工作区实际是小文本,内容类似:

version https://www.php.cn/link/34390147aa604589f654dca78ae78da3 oid sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 size 23

这不是 YAML 或 json,就是固定格式的键值对。C# 解析它不需要第三方库,File.ReadAllLines + 简单分割就能搞定。

用C#安全读取并提取oid和size

别直接 Split(':') 全局切分——字段值本身可能含冒号(比如未来扩展协议),必须按行解析、识别前缀。关键点:

  • oid 行格式严格为 "oid sha256:<hex>"</hex>,空格后才是哈希值,不能跳过空格直接取第二段
  • size 是十进制整数,但 Git LFS 规范允许带空格,建议用 int.TryParse(..., NumberStyles.Integer)
  • 文件可能损坏或非LFS指针(比如被误提交的普通文本),必须检查 version 行是否存在且匹配 "version https://www.php.cn/link/34390147aa604589f654dca78ae78da3"

示例片段:

var lines = File.ReadAllLines(pointerPath); string oid = null; int size = -1; <p>foreach (var line in lines) { if (line.StartsWith("version ") && !line.Contains("<a href="https://www.php.cn/link/34390147aa604589f654dca78ae78da3">https://www.php.cn/link/34390147aa604589f654dca78ae78da3</a>")) throw new InvalidOperationException("Not a valid LFS pointer");</p><pre class='brush:php;toolbar:false;'>if (line.StartsWith("oid ")) {     oid = line.Substring(4).Trim().Split(' ', 2)[1]; // 取"sha256:..."部分 } else if (line.StartsWith("size ")) {     if (!int.TryParse(line.Substring(5).Trim(), out size))         size = -1; }

}

为什么不能用JsonConvert.DeserializeObject

网上有人试过把指针当 JSON 解——会失败。因为:

  • 指针文件不是 JSON:没花括号、没引号、键名无引号、值含空格不转义
  • JsonConvert 强转只会抛 JsonReaderException,错误信息像 "After parsing a value an unexpected character was encountered"
  • 即使加了自定义 JsonTextReader 试图跳过格式校验,也绕不过语法层面的不兼容

硬套 JSON 库既没收益又埋异常风险,纯文本解析更轻、更稳、更可控。

注意跨平台换行和BOM

Windows 写的指针文件用 rnlinux/macosn;有些编辑器(尤其 VS)保存时可能加 UTF-8 BOM。这些都会影响 StartsWith 判断:

  • File.ReadAllLines 自动处理换行,不用自己 Split('n')
  • 读取前先用 File.ReadAllBytes 检查前3字节是否为 0xEF, 0xBB, 0xBF,若是 BOM,用 Encoding.UTF8 显式解码并跳过
  • 所有 StartsWith 调用前,确保字符串.TrimStart() —— BOM 或缩进空格会让匹配失败

指针文件看着简单,但生产环境里混着不同编辑器、CI 系统、Git 客户端版本,空白字符和编码才是最常翻车的地方。

text=ZqhQzanResources