Accesso casuale al file gzip in più parti (in Java)
-
22-07-2019 - |
Domanda
Ciò potrebbe rientrare nel campo di "non realmente fattibile" o "non vale davvero la pena" ma qui va.
Sto provando ad accedere casualmente ai record memorizzati all'interno di un file gzip in più parti. In particolare, i file che mi interessano sono compressi Heretrix file Arc. (Nel caso in cui non si abbia familiarità con i file gzip in più parti, la specifica gzip consente di concatenare più flussi gzip in un singolo file gzip. Non condividono alcuna informazione del dizionario, è semplicemente un binary.)
Sto pensando che dovrebbe essere possibile farlo cercando un certo offset all'interno del file, quindi cerca i byte dell'intestazione magica gzip (cioè 0x1f8b, come da RFC ) e prova a leggere il flusso gzip dai seguenti byte. Il problema con questo approccio è che quegli stessi byte possono apparire anche all'interno dei dati reali, quindi la ricerca di quei byte può portare a una posizione non valida da cui iniziare a leggere un flusso gzip. Esiste un modo migliore per gestire l'accesso casuale, dato che gli offset dei record non sono noti a priori?
Soluzione
Il design di GZIP, come hai capito, non è facile da usare per l'accesso casuale.
Puoi fare come descrivi, quindi se riscontri un errore nel decompressore, concludi che la firma che hai trovato era in realtà un dato compresso.
Se finisci di decomprimere, è facile verificare la validità dello stream appena decompresso, tramite CRC32.
Se i file non sono così grandi, potresti prendere in considerazione la decompressione di tutte le voci in serie e il mantenimento degli offset delle firme in modo da creare una directory. Durante la decompressione, scaricare i byte in un bit bucket. A quel punto avrai generato una directory e potrai quindi supportare l'accesso casuale basato su nome file, data o altri metadati.
Questo sarà ragionevolmente veloce per file inferiori a 100k. Come ipotesi, se avessi 10 file di circa 100k ciascuno, probabilmente sarebbe fatto in 2 secondi su una CPU moderna. Questo è ciò che intendo per "abbastanza veloce". Ma solo tu conosci i requisiti perf della tua applicazione.
Hai una classe GZipInputStream? Se è così sei a metà strada.
Altri suggerimenti
Il formato di file BGZF , compatibile con GZIP è stato sviluppato dai biologi.
(...) Il vantaggio di BGZF su gzip convenzionale è quello BGZF consente di cercare senza per scansionare l'intero file fino a la posizione richiesta.
In http: / /picard.svn.sourceforge.net/viewvc/picard/trunk/src/java/net/sf/samtools/util/ , dai un'occhiata a BlockCompressedOutputStream e BlockCompressedInputStream.java