12

Me gustaría poder hacer acceso aleatorio en un archivo comprimido. Puedo permitirme realizar un preprocesamiento (por ejemplo, crear algún tipo de índice), siempre que el resultado del preproceso sea mucho menor que el archivo en sí.Acceso aleatorio secuencia de gzip

¿Algún consejo?

Mis pensamientos fueron:

  • Hack en una aplicación existente y gzip serializar su estado descompresor cada, digamos, 1 megabyte de datos comprimidos. Luego, para hacer un acceso aleatorio, deserializar el estado del descompresor y leer desde el límite del megabyte. Esto parece difícil, especialmente porque estoy trabajando con Java y no pude encontrar una implementación de gzip pura-java :(
  • Vuelva a comprimir el archivo en trozos de 1Mb y haga lo mismo que antes. Esto tiene la desventaja de duplicar el espacio en disco requerido.
  • Escribir un analizador simple del formato gzip que no hace ninguna descompresión y solo detecta e indexa los límites del bloque (si aún hay bloques: aún no he leído la descripción del formato gzip)

Respuesta

6

Tener una mirada at this link (C ejemplo de código).

/* zran.c -- example of zlib/gzip stream indexing and random access 
... 

Gzip es solo zlib con un sobre.

+0

Gracias, eso es genial! Si tan solo encontrara una manera de usarlo cómodamente desde Java ... – jkff

+1

@jkff: si no necesita una implementación multiplataforma, consulte JNA. Es sorprendentemente fácil de usar como una forma de llamar a las bibliotecas C. –

+0

Gracias de nuevo, lo hice y funciona como un encanto!Rex, gracias a ti también: utilicé JNA :) – jkff

0

pregunta interesante. No entiendo por qué su segunda opción (recompress file in chunks) duplicaría el espacio en disco. Me parece que sería lo mismo, menos una pequeña cantidad de sobrecarga. Si tienes control sobre la pieza de compresión, entonces esa parece ser la idea correcta.

Quizás lo que quieres decir es que no tienes control sobre la entrada, y por lo tanto, se duplicaría.

Si puede hacerlo, imagino que lo modelaré como una clase CompressedFileStream que utiliza como almacén de respaldo, una serie de blobs gzip'd de 1mb. Al leer, un Seek() en la secuencia se moverá al blob apropiado y se descomprimirá. Una lectura() después del final de un blob provocaría que la secuencia abra el siguiente blob.

ps: GZIP se describe en IETF RFC 1952, pero usa DEFLATE para el formato de compresión. No habría ninguna razón para usar la elaboración de GZIP si implementó esta clase de CompressedFileStream tal como lo imaginé.

+0

No me gusta la segunda opción porque no voy a eliminar los archivos originales, y no tengo control sobre cómo se generan. Sin embargo, por ahora así es como realmente implementé el material (como dijiste), pero no estaba satisfecho con eso y por eso hice la pregunta :) – jkff

3

El formato de archivo BGZF, compatible con GZIP fue desarrollado por los biólogos.

(...) La ventaja de BGZF sobre gzip convencional es que BGZF permite la búsqueda sin tener para escanear a través de todo el archivo hasta la posición que se busca.

En http://picard.svn.sourceforge.net/viewvc/picard/trunk/src/java/net/sf/samtools/util/, echar un vistazo a BlockCompressedOutputStream y BlockCompressedInputStream.java

+2

Gracias, eso está bien, pero necesito que mi herramienta sea aplicable de inmediato archivos de registro existentes, y generalmente están archivados en .zip o .gzip por un archivador de terceros. Además, ya tengo una solución de trabajo :) – jkff

Cuestiones relacionadas