2011-10-21 8 views
6

Sto tentando di eseguire il debug di un OutOfMemoryException che si verifica quando si crea un file ZIP piuttosto grande utilizzando System.IO.Packaging.ZipPackage.OutOfMemoryException durante la creazione di file ZIP di grandi dimensioni mediante System.IO.Packaging

Il codice sta scorrendo un lungo elenco di oggetti, eseguendo le seguenti operazioni per ciascun oggetto.

  1. Serializzazione dei dati oggetto in un file temporaneo.
  2. Creazione di un PackagePart per il file.
  3. copia da una fonte System.IO.Stream ad un altro: flusso
    • Fonte: FileStream
    • flusso di destinazione: PackagePart::GetStream() =>MS.Internal.IO.Zip.ZipIOModeEnforcingStream

Infine chiama Package::Close() che salva il file.

Il problema che sto avendo è che per un elenco particolarmente grande di oggetti, sto vedendo un OutOfMemoryException (la dimensione del processo x86 arriva a circa 1,2 GB di dimensione).

Stavo pensando di suddividere i dati oggetto in blocchi, quindi elaboro solo una quantità minore per ciclo (ad esempio, i passaggi 1-3 sopra). L'idea è che vorrei creare i file ZIP n in una directory temporanea, e quindi trovare un modo per combinarli in un unico archivio.

È possibile utilizzare System.IO.Packaging? Cosa dovrei usare per combinare le parti?

O c'è un modo migliore per risolvere questo problema?

+0

Prova a chiamare Lavare tra l'iterazione durante la creazione di un nuovo pacchetto – Ankur

+0

@Ankur: l'hai inchiodato, che sembrava fare il trucco. Se aggiorni il tuo commento a una risposta, sarò felice di accettarlo. – LeopardSkinPillBoxHat

risposta

3

Chiamare il metodo Flush sull'oggetto Package tra la creazione di un nuovo pacchetto dovrebbe probabilmente risolvere il problema poiché ciò causerebbe il flush del buffer di memoria sul disco.

+0

Grazie - ha funzionato per me. Ho finito per farlo scorrere tra ogni 500 file che sono stati aggiunti al file ZIP. Questo è stato un buon compromesso tra memoria e prestazioni. – LeopardSkinPillBoxHat

0

Vorrei utilizzare la libreria DotNetZip (http://dotnetzip.codeplex.com/). Ho provato diverse librerie zip (System.IO come si sta attualmente utilizzando e anche SharpZibLib) e da lontano il più facile da usare è la libreria DotNetZip.

Quasi sicuramente ci saranno meno linee di codice e ho trovato che l'utilizzo della memoria è molto buono (ho avuto un problema in un ambiente di macchina virtuale che ho segnalato e una nuova versione lo ha risolto).

+0

La mia domanda originale non era molto chiara su questo, ma questo è in realtà un difetto nel codice esistente e non volevo dover riscrivere troppo questo codice (voglio solo risolvere il crash). Ho modificato la domanda per renderlo più chiaro. – LeopardSkinPillBoxHat

Problemi correlati