Декодирование объектов git / ошибка «Длина блока не совпадает с его дополнением» - PullRequest
5 голосов
/ 02 декабря 2011

Я застрял с очень простой, но раздражающей проблемой и не могу найти ответ в Интернете.Надеюсь, вы сможете указать мне, что я сделал неправильно.

Я пытаюсь декодировать объект из репозитория 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.

Любая идея будет принята с благодарностью!

Ответы [ 2 ]

7 голосов
/ 02 декабря 2011

DeflateStream и zlib это две разные вещи, как объяснено в этом ответе :

В библиотеке базовых классов .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);
}
2 голосов
/ 29 марта 2016

ZLib - это Deflate с дополнительным двухбайтовым заголовком, необязательным «словарем» и четырехбайтовой контрольной суммой в конце. В зависимости от вашего приложения - например, если вы знаете, что словаря не будет - вы можете избежать выделения первых двух байтов и последних четырех байтов из данных, прежде чем запускать их через DeflateStream. Это грязное решение, но может избавить вас от необходимости привлекать внешнюю зависимость.

...