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

发布于 2024-12-18 22:51:14 字数 1159 浏览 2 评论 0原文

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

我正在尝试从 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

帅气称霸 2024-12-25 22:51:14

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);
}

DeflateStream and zlib are two different things as explained in this answer:

There is no ZlibStream in the .NET base class library - nothing that
produces or consumes ZLIB

So what you need is a ZLIB consumer. The DotNetZip library provides one:

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);
}
余生再见 2024-12-25 22:51:14

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文