2013-03-11 10 views
19

Ho un file strano che quando viene compresso con DotNetZip crea un archivio "non convertibile". Quando provo a decomprimerlo con 7zip fallisce con CRC failed in 'AjaxControlToolkit.dll'. File is broken. Quando lo zip con 7zip manualmente scompatta bene.DotNetZip BadReadException on .Extract

Qualcuno si è imbattuto in uno scenario in cui DotNetZip non riesce a comprimere correttamente un semplice file binario? O sto usando DotNetZip in modo errato?

https://dl.dropbox.com/u/65419748/AjaxControlToolkit.dll

using System.IO; 
using Ionic.Zip; 

namespace ConsoleApplication1 
{ 
    public class Program 
    { 
     public static void Main(string[] args) 
     { 
      var source = new FileInfo(@"C:\ZipDemo\AjaxControlToolkit.dll"); 
      var target = new FileInfo(Path.ChangeExtension(source.FullName, "zip")); 
      var folder = new DirectoryInfo(Path.ChangeExtension(source.FullName, null)); 

      if (target.Exists) 
       target.Delete(); 

      if (folder.Exists) 
       folder.Delete(true); 

      using (var zip = new ZipFile(target.FullName)) 
      { 
       zip.AddFile(source.FullName, string.Empty); 
       zip.Save(); 
      } 

      using (var zip = new ZipFile(target.FullName)) 
       zip.ExtractAll(folder.FullName); 
     } 
    } 
} 

Produce:

Unhandled Exception: Ionic.Zip.BadReadException: bad read of entry AjaxControlToolkit.dll from compressed archive. 
    at Ionic.Zip.ZipEntry._CheckRead(Int32 nbytes) 
    at Ionic.Zip.ZipEntry.ExtractOne(Stream output) 
    at Ionic.Zip.ZipEntry.InternalExtract(String baseDir, Stream outstream, String password) 
    at Ionic.Zip.ZipFile._InternalExtractAll(String path, Boolean overrideExtractExistingProperty) 
    at Ionic.Zip.ZipFile.ExtractAll(String path) 
    at ConsoleApplication1.Program.Main(String[] args) in C:\ZipDemo\ConsoleApplication1\ConsoleApplication1\Program.cs:line 27 

Edit:

Se posso aggiungere un byte extra funziona bene, ma non è una soluzione accettabile. Non funziona senza lo + 1.

var bytes = new byte[source.Length + 1]; 
File.ReadAllBytes(source.FullName).CopyTo(bytes, 0); 
zip.AddEntry(source.Name, bytes); 

Aggiornamento:

rinunciato e passato a SharpZipLib in quanto non saltare in aria su estratto semplice, ma certo sarebbe bello sapere cosa non andava con DotNetZip, ha un'API più bello.

Update2:

Qualcosa circa la lunghezza del file di rende saltare in aria, 1179647 e 1179649 byte sono zip e decompressi correttamente.

var source = new FileInfo(@"C:\ZipDemo\foo.txt"); 
using (var writer = source.CreateText()) 
    writer.Write(new string('a', 1179648)); 
+0

E cosa succede se si tenta di decomprimere con qualche altro strumento, per esempio, WinRar? – Tigran

+0

@Tigran ottiene solo vari errori, cioè con l'estrattore di Windows incorporato ottengo 0x80004005 Errore non specificato. –

+0

Provare ZipArchive da .net 4.5, in System.IO.Compression, vedere se si ottiene lo stesso problema. Potrebbe essere un bug. –

risposta

15

La dimensione della dll è 53 * 128k (6954496/131072 = 53) e c'è un errore in DotNetZip come potete leggere qui: https://dotnetzip.codeplex.com/workitem/14087.Basta usare nel codice:

zip.ParallelDeflateThreshold = -1; 

ho avuto questo problema per molti file, è perfettamente funzionante ora;)

+0

ha funzionato anche con! Grazie mille :) – Rida

+0

Questo risolve lo stesso problema anche nel metodo di compressione file C# 4.5 :) –

+1

Grazie! Questa è la soluzione facile e sufficiente per me. La compilazione nella correzione suggerita da @laktak qui sotto è probabilmente l'opzione migliore, ma probabilmente non necessaria a meno che non si abbia davvero bisogno dell'ottimizzazione del deflating parallelo. È un peccato che il repository di codice ufficiale sembra essere stato inattivo dal 2011, non so se ce n'è uno più attivo che è stato aggiornato o meno. – Chaser324

2

ho provato questo -

  • installare l'ultima versione di DotNetZip
  • eseguire il codice.
  • Hai il BadReadException

Allora questo -

  • installare una versione precedente (1.9) del DotNetZip. (Install-Package DotNetZip -Version 1.9)
  • Esegui il codice
  • Il codice funziona correttamente.

Immagino che questo potrebbe essere un bug?

+0

Sembra che sia stato inviato un errore http://dotnetzip.codeplex.com/workitem/16092 non è in grado di capire se ce ne sono altri simili, sembra che CodePlex stesso sia borked e non mostri le descrizioni del workitem. –

+1

Fresco. Ho aggiornato il tuo bug con l'esempio che potrei ottenere lavorando, dovrebbe essere utile per chiunque la risoluzione dei problemi. –

+0

non è la soluzione! Quando cambi versione, le dimensioni cambiano, quindi non vedi il problema ... per ora. Ma il prossimo aggiornamento, il problema può nuovamente verificarsi! – Xaruth

4

È un bug - è possibile risolvere il problema in Zlib\ParallelDeflateOutputStream.cs.

cambiamento

} while (doAll && (_lastWritten != _latestCompressed)); 

a

} while (doAll && (_lastWritten != _lastFilled)); 

Vedi https://dotnetzip.codeplex.com/workitem/14087 per maggiori informazioni.