Formatos de compresión con buen soporte para el acceso aleatorio dentro de los archivos?


Esto es similar a una pregunta anterior , pero las respuestas no satisfacen mis necesidades y mi pregunta es ligeramente diferente:

Actualmente uso la compresión gzip para algunos archivos muy grandes que contienen datos ordenados. Cuando los archivos no están comprimidos, la búsqueda binaria es una forma práctica y eficiente de apoyar la búsqueda de una ubicación en los datos ordenados.

Pero cuando los archivos están comprimidos, las cosas se ponen complicadas. Recientemente me enteré de zlib's Z_FULL_FLUSH opción, que se puede utilizar durante la compresión para insertar "puntos de sincronización" en la salida comprimida (inflateSync() puede comenzar a leer desde varios puntos en el archivo). Esto está bien, aunque los archivos que ya tengo tendrían que ser recomprimidos para agregar esta característica (y extrañamente gzip no tiene una opción para esto, pero estoy dispuesto a escribir mi propio programa de compresión si debo).

Parece Que de una fuente que incluso Z_FULL_FLUSH no es una solución perfecta...no solo no es compatible con todos los gzip archivos, pero la misma idea de detectar puntos de sincronización en los archivos puede producir falsos positivos (ya sea por coincidencia con el número mágico de puntos de sincronización, o debido al hecho de que Z_SYNC_FLUSH también produce puntos de sincronización, pero no son utilizables para el acceso aleatorio).

¿Hay una solución mejor? Me gustaría evitar tener archivos auxiliares para indexar si es posible, y el soporte explícito por defecto para el acceso cuasi-aleatorio sería útil (incluso si es de gran grano--como poder comenzar a leer en cada intervalo de 10 MB). ¿Hay otro formato de compresión con mejor soporte para lecturas aleatorias que gzip?

Edit : Como mencioné, deseo hacer una búsqueda binaria en los datos comprimidos. No necesito buscar una posición específica (sin comprimir) only solo buscar con cierta granularidad gruesa dentro del archivo comprimido. Solo quiero soporte para algo como "Descomprimir los datos a partir de aproximadamente 50% (25%, 12.5%, etc.) de la manera en este archivo comprimido."

Author: Community, 2009-01-10

12 answers

No conozco ningún formato de archivo comprimido que admita el acceso aleatorio a una ubicación específica en los datos sin comprimir (bueno, a excepción de los formatos multimedia), pero puede elaborar el suyo propio.

Por ejemplo, los archivos comprimidos bzip2 se componen de bloques comprimidos independientes de tamaño

Aún así, creo que la mejor solución sería dividir el archivo en trozos de su elección, y luego comprimirlo con algún archivador, como zip o rar, que admite el acceso aleatorio a archivos individuales en el archivo.

 17
Author: jpalecek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-09 23:33:07

Echa un vistazo a dictzip. Es compatible con gzip y permite el acceso aleatorio grueso.

Un extracto de su página de manual:

Dictzip comprime archivos usando el algoritmo gzip(1) (LZ77) de una manera que es completamente compatible con el formato de archivo gzip. Una extensión del gzip el formato de archivo (Campo adicional, descrito en 2.3.1.1 de RFC 1952) permite datos adicionales para ser almacenado en el encabezado de un archivo comprimido. Programas como gzip y zcat ignorará estos datos adicionales. Sin embargo, [dictzcat start start] hará uso de estos datos para realizar un acceso pseudo-aleatorio en el archivo.

Tengo el paquete dictzip en Ubuntu. O su código fuente está en un dictd-*.alquitrán.gz . Su licencia es GPL. Eres libre de estudiarlo.

Actualización:

He mejorado dictzip para que no tenga límite de tamaño de archivo. Mi implementación está bajo licencia MIT.

 30
Author: Ivo Danihelka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-21 22:11:49

El .el formato de archivo xz (que usa compresión LZMA) parece soportar esto:

Lectura de acceso aleatorio: Los datos se pueden dividir en bloques comprimidos independientemente. Cada .el archivo xz contiene un índice de los bloques, lo que hace posible la lectura de acceso aleatorio limitado cuando el tamaño del bloque es lo suficientemente pequeño.

Esto debería ser suficiente para su propósito. Un inconveniente es que la API de liblzma (para interactuar con estos contenedores) no parece que bien documentado, por lo que puede tomar algún esfuerzo averiguar cómo acceder aleatoriamente a los bloques.

 8
Author: AardvarkSoup,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-03 11:53:47

Existen soluciones para proporcionar acceso aleatorio a los archivos gzip y bzip2:

(estoy buscando algo para 7zip)

 7
Author: hippietrail,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-17 01:42:32

bgzip puede comprimir archivos en una variante gzip que es indexable (y puede ser descomprimida por gzip). Esto se utiliza en algunas aplicaciones bioinformáticas, junto con el indexador tabix.

Ver explicaciones aquí: http://blastedbio.blogspot.fr/2011/11/bgzf-blocked-bigger-better-gzip.html , y aquí: http://www.htslib.org/doc/tabix.html .

No se hasta que punto es adaptable a otras aplicaciones.

 4
Author: bli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-01 18:29:29

No estoy seguro de si esto sería práctico en su situación exacta, pero ¿no podría simplemente gzip cada archivo grande en archivos más pequeños, digamos 10 MB cada uno? Terminarías con un montón de archivos: file0.gz, file1.gz, file2.gz, etc. Basado en un desplazamiento dado dentro del large original, puede buscar en el archivo llamado "file" + (offset / 10485760) + ".gz". El desplazamiento dentro del archivo sin comprimir sería offset % 10485760.

 3
Author: William Brendel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-10 06:43:51

Porque la compresión sin pérdida funciona mejor en algunas áreas que en otras, si almacena datos comprimidos en bloques de tamaño de bloque de longitud conveniente, a pesar de que cada bloque tiene exactamente el mismo número de bytes comprimidos, algunos bloques comprimidos se expandirán a una pieza de texto plano mucho más larga que otros.

Usted podría mirar "Compresión: Una Clave para los Sistemas de Recuperación de Texto de Próxima Generación" por Nivio Ziviani, Edleno Silva de Moura, Gonzalo Navarro y Ricardo Baeza-Yates en Computer magazine Noviembre 2000 http://doi.ieeecomputersociety.org/10.1109/2.881693

Su descompresor toma 1, 2 o 3 bytes completos de datos comprimidos y descomprime (usando una lista de vocabulario) en una palabra completa. Uno puede buscar directamente en el texto comprimido palabras o frases, que resulta ser incluso más rápido que buscar texto sin comprimir.

Su descompresor le permite apuntar a cualquier palabra en el texto con un puntero normal (byte) y empieza a descomprimir inmediatamente desde ese punto.

Puede dar a cada palabra un código único de 2 bytes, ya que probablemente tenga menos de 65,000 palabras únicas en su texto. (Hay casi 13,000 palabras únicas en la Biblia KJV). Incluso si hay más de 65,000 palabras, es bastante simple asignar los primeros 256 "palabras" de código de dos bytes a todos los bytes posibles, para que pueda deletrear palabras que no están en el léxico de las aproximadamente 65,000 "palabras y frases más frecuentes". (La compresión ganada por empaquetar palabras y frases frecuentes en dos bytes generalmente vale la pena la "expansión" de ocasionalmente deletrear una palabra usando dos bytes por letra). Hay una variedad de maneras de elegir un léxico de "palabras y frases frecuentes" que le dará una compresión adecuada. Por ejemplo, podría modificar un compresor LZW para volcar "frases" que usa más de una vez en un archivo de léxico, una línea por frase, y ejecutarlo sobre todos sus datos. O puede cortar arbitrariamente sus datos sin comprimir en frases de 5 bytes en un archivo de léxico, una línea por frase. O podría cortar sus datos sin comprimir en palabras reales en inglés, y poner cada palabra-incluyendo el espacio al principio de la palabra-en el archivo de léxico. Luego use "ordenar unique único" para eliminar palabras duplicadas en ese archivo de léxico. (¿Escoger la lista de palabras del léxico "óptimo" perfecto todavía se considera NP-difícil?)

Almacenar el léxico al principio de su archivo comprimido enorme, pad hacia fuera a algún TAMAÑO DE BLOQUE conveniente, y luego almacenar el texto comprimido a una serie de dos bytes "palabras" from desde allí hasta el final del archivo. Presumiblemente, el buscador leerá este léxico una vez y lo mantendrá en un formato rápido de decodificación en RAM durante la descompresión, para acelerar la descompresión de" código de dos bytes "a"frase de longitud variable". Mi primer borrador comenzaría con una simple lista de una línea por frase, pero más tarde podría cambiar a almacenar el léxico en una forma más comprimida utilizando algún tipo de codificación incremental o zlib.

Puedes elegir cualquiera desplazamiento aleatorio de bytes en el texto comprimido, y comenzar a descomprimir desde allí. No creo que sea posible hacer un formato de archivo comprimido de acceso aleatorio de grano más fino.

 3
Author: David Cary,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-07 20:52:23

Dos posibles soluciones:

  1. Deje que el sistema operativo se ocupe de la compresión, cree y monte un sistema de archivos comprimidos (SquashFS, clic, cloop, cramfs, e2compr o lo que sea) que contenga todos sus archivos de texto y no haga nada sobre la compresión en su programa de aplicación.

  2. Utilice clicfs directamente en cada archivo de texto (un clic por archivo de texto) en lugar de comprimir una imagen del sistema de archivos. Piense en "mkclicfs mytextfile mycompressedfile "siendo" gzip mycompressedfile " and " clicfs mycompressedfile directory "as a way of getting random access to the data via the file"directory/mytextfile".

 1
Author: Joachim Wagner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-10 18:32:39

No sé si se ha mencionado todavía, pero el proyecto Kiwix había hecho un gran trabajo en este sentido. A través de su programa Kiwix, ofrecen acceso aleatorio a los archivos de archivos ZIM. Buena compresión, también. El proyecto se originó cuando hubo una demanda de copias fuera de línea de la Wikipedia (que ha alcanzado más de 100 GB en forma sin comprimir, con todos los medios incluidos). Han tomado con éxito un archivo de 25 GB (una encarnación de un solo archivo de wikipedia sin la mayoría de los medios) y lo comprimieron a un mísero archivo zim de 8 GB. Y a través del programa Kiwix, puede llamar a cualquier página de la Wikipedia, con todos los datos asociados, más rápido de lo que puede navegar por la red.

Aunque el programa Kiwix es una tecnología basada en la estructura de la base de datos de wikipedia, demuestra que puede tener excelentes relaciones de compresión y acceso aleatorio simultáneamente.

 1
Author: CogitoErgoCogitoSum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-08 03:14:55

Esta es una pregunta muy antigua, pero parece que zindex podría proporcionar una buena solución (aunque no tengo mucha experiencia con ella)

 1
Author: robochat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-04 07:26:19

Razip admite el acceso aleatorio con mejor rendimiento que gzip / bzip2, que deben ajustarse para este soporte, reduciendo la compresión a expensas del acceso aleatorio" ok":

Http://sourceforge.net/projects/razip /

 0
Author: Erik Aronesty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-23 15:07:36

Soy el autor de una herramienta de código abierto para comprimir un tipo particular de datos biológicos. Esta herramienta, llamada starch, divide los datos por cromosoma y utiliza esas divisiones como índices para un acceso rápido a las unidades de datos comprimidos dentro del archivo más grande.

Los datos por cromosoma se transforman para eliminar la redundancia en coordenadas genómicas, y los datos transformados se comprimen con algoritmos bzip2 o gzip. Las compensaciones, los metadatos y los datos genómicos comprimidos se concatenan en un archivo.

El código fuente está disponible en nuestro sitio GitHub. Lo hemos compilado bajo Linux y Mac OS X.

Para su caso, podría almacenar (10 MB, o lo que sea) compensaciones en un encabezado a un formato de archivo personalizado. Analizas el encabezado, recuperas las compensaciones, y de forma incremental fseek a través del archivo por current_offset_sum + header_size.

 0
Author: Alex Reynolds,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-29 21:04:29