2012-05-20 8 views
10

Quando decomprimere i file in Windows, io a volte problemi con i percorsiCome gestire decomprimere ZipFile con percorsi che sono troppo lunghi/duplicare

  1. che sono troppo lunghi per Windows (ma va bene nel sistema operativo originale che creato il file).
  2. che sono "duplicato" a causa di caso-insensibilità

Utilizzando DotNetZip, la chiamata sarà ZipFile.Read(path) merda ogni volta che la lettura di file zip con uno di questi problemi. Il che significa che non posso nemmeno provare a filtrarlo.

using (ZipFile zip = ZipFile.Read(path)) 
{ 
    ... 
} 

Qual è il modo migliore per gestire la lettura di questi tipi di file?

Aggiornato:

Esempio zip da qui: https://github.com/MonoReports/MonoReports/zipball/master

Duplicati: https://github.com/MonoReports/MonoReports/tree/master/src/MonoReports.Model/DataSourceType.cs https://github.com/MonoReports/MonoReports/tree/master/src/MonoReports.Model/ DatasourceType.cs

Ecco più in dettaglio sulla eccezione:

Ionic.Zip.ZipException: impossibile leggere come file zip
---> System.ArgumentException: un elemento> con la stessa chiave è già stato aggiunto.
a System.ThrowHelper.ThrowArgumentException (risorsa ExceptionResource)
a System.Collections.Generic.Dictionary 2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary
2.Add (chiave TKey, TValue valore)
a Ionic.Zip.ZipFile.ReadCentralDirectory (ZipFile ZF)
a Ionic.Zip.ZipFile.ReadIntoInstance (ZipFile ZF)

Risoluzione:

sulla base @ suggerimento di Cheeso, posso leggere tutto dal flusso, quelle duplicati evitando, e problemi di percorso:

//using (ZipFile zip = ZipFile.Read(path)) 
using (ZipInputStream stream = new ZipInputStream(path)) 
{ 
    ZipEntry e; 
    while((e = stream.GetNextEntry()) != null) 
    //foreach(ZipEntry e in zip) 
    { 
     if (e.FileName.ToLower().EndsWith(".cs") || 
      e.FileName.ToLower().EndsWith(".xaml")) 
     { 
      //var ms = new MemoryStream(); 
      //e.Extract(ms); 
      var sr = new StreamReader(stream); 
      { 
       //ms.Position = 0; 
       CodeFiles.Add(new CodeFile() { Content = sr.ReadToEnd(), FileName = e.FileName }); 
      } 
     } 
    } 
} 
+0

Il file .zip o .gz? – SimpleVar

+0

.zip (in particolare dai download di github zipfile) – gameweld

+0

Puoi mostrare l'errore? È il percorso all'interno del file? La posizione del file di destinazione è troppo lunga? – yamen

risposta

3

Leggilo con ZipInputStream.

La classe ZipFile mantiene una raccolta utilizzando il nome file come indice. I nomi file duplicati infrangono quel modello.

Ma è possibile utilizzare ZipInputStream per leggere nel file zip. In questo caso non esiste una raccolta o un indice.

8

Per il problema PathTooLongException, ho rilevato che non è possibile utilizzare DotNetZip. Invece, quello che ho fatto è stato invocare il command-line version of 7-zip; questo fa miracoli.

public static void Extract(string zipPath, string extractPath) 
{ 
    try 
    { 
     ProcessStartInfo processStartInfo = new ProcessStartInfo 
     { 
      WindowStyle = ProcessWindowStyle.Hidden, 
      FileName = Path.GetFullPath(@"7za.exe"), 
      Arguments = "x \"" + zipPath + "\" -o\"" + extractPath + "\"" 
     }; 
     Process process = Process.Start(processStartInfo); 
     process.WaitForExit(); 
     if (process.ExitCode != 0) 
     { 
      Console.WriteLine("Error extracting {0}.", extractPath); 
     } 
    } 
    catch (Exception e) 
    { 
     Console.WriteLine("Error extracting {0}: {1}", extractPath, e.Message); 
     throw; 
    } 
} 
+2

Questa è in realtà la soluzione più semplice che ho trovato. Al momento di questo commento, potrebbe essere utile sapere che il 7za.exe si trova nei download di 7-zip con "7-zip extra: ...." nella descrizione. (http://www.7-zip.org/download.html) –

+0

La riga 'Arguments' non è corretta; dovrebbe essere 'Arguments =" x \ "" + zipPath + "\" -o \ "" + extractPath + "\" "' (non notare spazio tra il ** o ** switch e 'extractPath'. – sigil

+0

Grazie @ sigil, secondo [questo] (http://superuser.com/questions/95902/7-zip-and-unzipping-from-command-line) hai ragione, ho aggiornato la mia risposta –