解码git对象/“块长度与其补码不匹配”错误

我陷入了非常简单但烦人的问题,并且无法在互联网上找到答案。 希望你能指出我,我做错了什么。

我正在尝试从Git存储库中解码对象。 根据ProGit ,文件名及其内容在提交期间已被缩小。

我正在使用C#将SHA1指示的对象读入流中,将其充气并转换为字节数组。 这是代码:

using System.IO.Compression; static internal byte[] GetObjectBySha(string storagePath, string sha) { string filePath = Path.Combine(storagePath, "objects", sha.Substring(0, 2), sha.Substring(2, 38)); byte[] fileContent = null; using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { using (MemoryStream ms = new MemoryStream()) { using (DeflateStream gs = new DeflateStream(fs, CompressionMode.Decompress)) { gs.CopyTo(ms); } fileContent = ms.ToArray(); } } return fileContent; } 

gs.CopyTo(ms); 到达时发生运行时错误: 块长度与其补码不匹配。

为什么这样?

关于我正在尝试阅读的文件的内容……它是二进制的,它是由git可执行文件创建的。 原始文件名是testfile.txt ,它的内容是Sample text. SHA1是51d0be227ecdc0039698122a1513421ce35c1dbe

任何想法将不胜感激!

DeflateStreamzlib是两个不同的东西,如本答案中所解释的:

.NET基类库中没有ZlibStream – 没有任何生成或使用ZLIB的东西

所以你需要的是一个ZLIB消费者。 DotNetZip库提供了一个:

 static internal byte[] GetObjectBySha(string storagePath, string sha) { string filePath = Path.Combine(storagePath, "objects", sha.Substring(0, 2), sha.Substring(2, 38)); byte[] compressed = File.ReadAllBytes(filePath); return Ionic.Zlib.ZlibStream.UncompressBuffer(compressed); } 

ZLib是Deflate,带有一个额外的两个字节的头,一个可选的“字典”和一个四字节校验和。 根据您的应用程序 – 如果您知道不会有字典 – 您可以在通过DeflateStream运行之前切断数据的前两个字节和最后四个字节。 它是一个肮脏的解决方案,但可以帮助您避免引入外部依赖。