2011-12-02 7 views
5

Sono bloccato con un problema molto semplice ma fastidioso e non riesco a trovare la risposta su Internet. Spero che sarai in grado di indicarmi cosa ho fatto di sbagliato.Decodifica oggetti git/Errore "La lunghezza del blocco non corrisponde al relativo complemento"

Sto cercando di decodificare l'oggetto dal repository Git. Secondo ProGit, il nome del file e il suo contenuto sono stati sgonfiati durante il commit.

Sto usando C# per leggere l'oggetto indicato da SHA1 in un flusso, gonfiarlo e convertirlo in array di byte. Ecco il codice:

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

Quando gs.CopyTo(ms); viene raggiunto l'errore di runtime si è verificato: Lunghezza blocco non corrisponde con il suo complemento.

Perché così?

Per quanto riguarda il contenuto del file che sto cercando di leggere ... E 'binario ed è stato creato da eseguibile git. Il nome del file originale è testfile.txt, il suo contenuto è Sample text. lo SHA1 è 51d0be227ecdc0039698122a1513421ce35c1dbe.

Qualsiasi idea sarebbe molto apprezzata!

risposta

7

DeflateStream e zlib sono due cose diverse, come spiegato nel this answer:

Non c'è ZlibStream nella libreria di classi di base .NET - niente che produce o consuma ZLIB

Quindi, ciò che è necessario un consumatore ZLIB. La biblioteca DotNetZip prevede 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); 
} 
+0

Grazie, questo è stato veramente utile! – shytikov

2

ZLib è Sgonfiare con un ulteriore byte di intestazione due, un "dizionario" opzionale e un checksum quattro byte alla fine. A seconda dell'applicazione - come se si sa non ci sta per essere un dizionario - si può essere in grado di cavarsela con tagliando i primi due byte e ultimi quattro byte dai dati prima di eseguirlo attraverso il DeflateStream. È una soluzione sporca, ma potrebbe salvarti dal dover creare una dipendenza esterna.

Problemi correlati