Pregunta

Según una sección en este libro presumiblemente exacto ,

  

Un uso común de las tuberías es leer un   archivo comprimido incrementalmente; ese   Es, sin descomprimir el conjunto.   cosa a la vez. La siguiente funcion   Toma el nombre de un archivo comprimido como   un parámetro y devuelve un tubo que   usa gunzip para descomprimir el   contenidos:

 def open_gunzip(filename):
     cmd = 'gunzip -c ' + filename
     fp = os.popen(cmd)
     return fp
     

Si lees líneas de fp uno en un   tiempo, nunca tienes que almacenar el   archivo sin comprimir en la memoria o en   disco.

Tal vez solo estoy interpretando esto mal, pero no veo cómo esto es posible. Python no podía tener ningún medio para detener Gunzip a mitad de camino a través de escupir los resultados, ¿verdad? Supongo que gunzip no se bloqueará hasta que se lea una línea de salida antes de continuar con más líneas, por lo que algún búfer tiene que capturar todo esto (ya sea dentro del intérprete de Python o en el sistema operativo, ya sea en la memoria o en el disco ), lo que significa que el archivo sin comprimir se está almacenando en algún lugar en su totalidad ... ¿verdad?

¿Fue útil?

Solución

Su suposición es defectuosa. Gunzip no tiene que ver el archivo completo para descomprimirlo. Lea el formato de archivo descomprimir. Hay un directorio, con compensaciones para los componentes individuales.

Es posible descomprimir un archivo en pedazos.

" el archivo sin comprimir se está almacenando en algún lugar en su totalidad ... ¿verdad? "

No necesariamente. No estoy seguro de por qué lo estás asumiendo o dónde lo lees.

Se pueden bloquear todas las llamadas de E / S de bajo nivel. La escritura en gunzip, cuando se escribe en una tubería, puede bloquearse cuando la tubería está llena. Así se define la E / S a una tubería. Bloques de E / S de tuberías.

Revise las páginas de manual para obtener más información.

  

Si un proceso intenta leer desde un   tubo vacío, luego leer (2) lo hará
  Bloquear hasta que los datos estén disponibles. Si   un proceso intenta escribir a un usuario   tubo completo (ver más abajo), luego escriba (2)   Bloques hasta que suficientes datos tengan
  sido leído desde la tubería para permitir que el   escribir para completar No bloqueo
  I / O es posible usando el fcntl (2)   Operación F_SETFL para habilitar el
  O_NONBLOCK abre el indicador de estado del archivo.

Otros consejos

Esto realmente viene de la implementación de gunzip , no de python. Está escrito en C. Probablemente usa fwrite () del stdio.h de C para escribir su salida.

La implementación de

libc6 que uso automáticamente crea un búfer de salida, y cuando se llena, se bloquea en fwrite () hasta que pueda escribir más.

No es Python lo que suspende gunzip , es que el kernel dejará de ejecutar gunzip cuando intente escribir (utilizando write () syscall) a un búfer completo. Esto se denomina bloqueo en IO . El kernel mantiene un búfer interno que conecta los dos extremos de la línea de tubería, independientemente de cualquier búfer que ocurra en cualquier proceso que esté escribiendo o leyendo desde la tubería.

Python se bloqueará de manera similar cuando lea desde una tubería que tiene un búfer vacío, es decir, que actualmente no tiene ningún dato de gunzip escrito en él.

Los tubos se pueden ver como una solución para el Problema del productor-consumidor .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top