解码 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
。
任何想法将不胜感激!
I'm stuck with very simple but annoying issue, and cannot find answer on the Internet. Hope you will be able to point me, what I've done wrong.
I'm trying to decode object from Git repository. According to ProGit, file name and it's contents have been deflated during commit.
I'm using C# to read object indicated by SHA1 into a stream, inflate it and convert into byte array. Here is the code:
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;
}
When gs.CopyTo(ms);
is reached the runtime error occurs: Block length does not match with its complement.
Why so?
Regarding the content of the file I'm trying to read... It's binary and it was created by git executable. The original file name is testfile.txt
, it's content is Sample text.
the SHA1 is 51d0be227ecdc0039698122a1513421ce35c1dbe
.
Any idea would be greatly appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
DeflateStream
和zlib
是两个不同的东西,如这个答案中所述:所以你需要的是一个 ZLIB 消费者。 DotNetZip 库提供了一个:
DeflateStream
andzlib
are two different things as explained in this answer:So what you need is a ZLIB consumer. The DotNetZip library provides one:
ZLib 是 Deflate,带有附加的两字节标头、可选的“字典”和末尾的四字节校验和。根据您的应用程序(例如,如果您知道不会有字典),您可能可以在通过 DeflateStream 运行数据之前从数据中删除前两个字节和最后四个字节。这是一个肮脏的解决方案,但可以使您不必引入外部依赖项。
ZLib is Deflate with an additional two byte header, an optional "dictionary" and a four byte checksum at the end. Depending on your application - like if you know there isn't going to be a dictionary - you may be able to get away with chopping off the first two bytes and last four bytes from the data before running it through the DeflateStream. Its a dirty solution, but could save you from having to bring in an external dependency.