Is there a library for gzip and bzip2 that supports Seek
operations?
I understand that it is not trivial (in the sense of O(1)
) to seek an arbitrary compressed stream.
My use case is that I want to read something similar to a tgz archive,
and I want to jump to the start of an arbitrary file entry in the archive
without re-inflating all the contents before the file I want to seek.
One possible implementation is with this pseudocode:
let mut tar = GzipReader::new(&file);
let mut entries = vec![];
for _ in 0..num_files {
entries.push(read_entry(&mut tar));
}
for entry in &mut entries {
entry.seek = file.seek(SeekFrom::Current(0))?;
entry.read_state = tar.clone();
}
fn read_file(index: usize) -> impl Read {
let entry = &entries[index];
file.seek(SeekFrom::Start(entry.seek))?;
entry.read_state.take(entry.file_size)
}
then read_file
effectively seeks to the offset at the start of file below the gzip layer.
However, apparently, current compression crates (flate2 and bzip2) do not support use of Clone
like this; the shared nature of std::fs::File
is also not compatible with all Read
implementations.
Is there a more idiomatic way to solve this problem? Are there compression libraries dedicated to solving this?