La deencoding de los objects de Git / error "La longitud del bloque no coincide con su complemento"

Estoy atrapado con un problema muy simple pero molesto, y no puedo encontrar una respuesta en Internet. Espero que puedas señalarme, lo que he hecho mal.

Estoy tratando de descodificar objects del repository de Git. Según ProGit , el nombre del file y su contenido se desinflaron durante la confirmación.

Estoy usando C # para leer el object indicado por SHA1 en una secuencia, inflarlo y convertirlo en una matriz de bytes. Aquí está el código:

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

Cuando gs.CopyTo(ms); se alcanza, se produce el error de time de ejecución: la longitud del bloque no coincide con su complemento.

¿Porque?

En cuanto al contenido del file que bash leer … Es binary y fue creado por el ejecutable git. El nombre del file original es testfile.txt , su contenido es Sample text. el SHA1 es 51d0be227ecdc0039698122a1513421ce35c1dbe .

¡Cualquier idea sería muy apreciada!

DeflateStream y zlib son dos cosas diferentes, como se explica en esta respuesta :

No hay ZlibStream en la biblioteca de classs base .NET, nada que produzca o consum ZLIB

Entonces, lo que necesitas es un consumidor de ZLIB. La biblioteca DotNetZip proporciona uno:

 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 se desinfla con un encabezado adicional de dos bytes, un "dictionary" opcional y una sum de comprobación de cuatro bytes al final. Dependiendo de su aplicación, por ejemplo, si sabe que no va a haber un dictionary, puede salirse con la tarea cortando los primeros dos bytes y los últimos cuatro bytes de los datos antes de ejecutarlo a través de DeflateStream. Es una solución sucia, pero podría salvarte de tener que traer una dependencia externa.

    Intereting Posts