2011-10-21 18 views
6

Estoy intentando depurar un OutOfMemoryException que se produce al crear un archivo bastante grande ZIP utilizando System.IO.Packaging.ZipPackage.OutOfMemoryException al crear un archivo ZIP de gran tamaño utilizando System.IO.Packaging

El código se repite en una gran lista de objetos, haciendo lo siguiente para cada objeto.

  1. serialización de los datos del objeto en un archivo temporal.
  2. Creando un PackagePart para el archivo.
  3. Copia de una fuente a otra System.IO.Stream: flujo
    • Fuente: FileStream
    • flujo Objetivo: PackagePart::GetStream() =>MS.Internal.IO.Zip.ZipIOModeEnforcingStream

finalmente llama Package::Close() la que guarda el archivo.

El problema que tengo es que para una lista particularmente grande de objetos, estoy viendo un OutOfMemoryException (el tamaño del proceso x86 es de aproximadamente 1.2GB de tamaño).

Estaba pensando en dividir los datos del objeto en fragmentos, por lo que solo proceso una cantidad menor por ciclo (es decir, los pasos 1-3 anteriores). La idea es crear archivos ZIP n en un directorio temporal, y luego encontrar una forma de combinarlos en un solo archivo.

¿Es esto posible usando System.IO.Packaging? ¿Qué usaría para combinar las partes?

¿O existe una forma mejor de corregir esto?

+0

Intenta llamar a Flush entre la iteración cuando creas un nuevo paquete – Ankur

+0

@Ankur: ya lo has encontrado, eso pareció ser el truco. Si actualizas tu comentario a una respuesta, estaré encantado de aceptarlo. – LeopardSkinPillBoxHat

Respuesta

3

Llamar al método Flush en el objeto Paquete entre la creación de un nuevo paquete probablemente debería resolver el problema, ya que eso provocaría que el búfer de memoria se vacíe en el disco.

+0

Gracias - esto funcionó para mí. Terminé de enjuagarlo entre cada 500 archivos que se agregaron al archivo ZIP. Esta fue una buena compensación entre la memoria y el rendimiento. – LeopardSkinPillBoxHat

0

Utilizaría la biblioteca DotNetZip (http://dotnetzip.codeplex.com/). He intentado varias bibliotecas zip (System.IO como usted está utilizando actualmente y también SharpZibLib) y por ahora la más fácil de usar es la biblioteca DotNetZip.

Seguramente terminará con menos líneas de código y el uso de memoria me pareció muy bueno (tuve un problema en un entorno de máquina virtual que informé y una nueva versión lo arregló).

+0

Mi pregunta original no era muy clara sobre esto, pero esto es en realidad un defecto en el código existente y no quería tener que volver a escribir este código demasiado (solo quiero arreglar el bloqueo). Edité la pregunta para aclarar esto. – LeopardSkinPillBoxHat

Cuestiones relacionadas