dyz1990 / sevenz-rust

A 7z decompressor/compressor lib written in pure rust
Apache License 2.0
153 stars 24 forks source link

How to decompress part of 7z to memory? #13

Closed oovm closed 1 year ago

oovm commented 1 year ago

I need to decompress a single file in a huge archive(&Path) into memory(&mut Vec<u8>), how should I do it?

In fact, I still want to modify this file and write it back, can it be done?

oovm commented 1 year ago

Very strange, I can't read the file name in the 7z, here is the file.

diffuser-types.gz, this is a 7z file, github prohibits uploading 7z, so I changed it to gz.

    let mut reader = SevenZReader::open("xxx.7z", Password::empty()).unwrap();
    reader.for_each_entries(|f, _|
        {
            println!("{:?}", f.name()); // all outputs are `""`
            Ok(true)
        }
    ).unwrap();

And if it is solid compression, it will generate a meaningless BadSignature(106) error, I think the error message can be improved.


When the file config.json I want to write exists, an error will be reported, how do i force overwrite this?

    let mut writer = SevenZWriter::new(File::open("test.7z").unwrap()).unwrap();
    let buffer = b"{}".as_slice();
    let mut entry = SevenZArchiveEntry::default();
    entry.name = "config.json".to_string();
    writer.push_archive_entry(entry, Some(buffer)).unwrap(); // Os { code: 5, kind: PermissionDenied }
    writer.finish().unwrap()
dyz1990 commented 1 year ago

Very strange, I can't read the file name in the 7z, here is the file.

diffuser-types.gz, this is a 7z file, github prohibits uploading 7z, so I changed it to gz.

    let mut reader = SevenZReader::open("xxx.7z", Password::empty()).unwrap();
    reader.for_each_entries(|f, _|
        {
            println!("{:?}", f.name()); // all outputs are `""`
            Ok(true)
        }
    ).unwrap();

And if it is solid compression, it will generate a meaningless BadSignature(106) error, I think the error message can be improved.

When the file config.json I want to write exists, an error will be reported, how do i force overwrite this?

    let mut writer = SevenZWriter::new(File::open("test.7z").unwrap()).unwrap();
    let buffer = b"{}".as_slice();
    let mut entry = SevenZArchiveEntry::default();
    entry.name = "config.json".to_string();
    writer.push_archive_entry(entry, Some(buffer)).unwrap(); // Os { code: 5, kind: PermissionDenied }
    writer.finish().unwrap()
  1. Well, you found a bug in the read_files_info method that case entry.name is empty. I will fix it right now.
  2. Is 'test.7z' file already exists and ready only?
oovm commented 1 year ago

test.7z already exists, and is not a solid compression

config.json also already exists, what I want to do is to rewrite config.json without changing/recompress other files, and config.json will be bigger than the original.

Is this possible for 7z format?

dyz1990 commented 1 year ago

test.7z already exists, and is not a solid compression

config.json also already exists, what I want to do is to rewrite config.json without changing/recompress other files, and config.json will be bigger than the original.

Is this possible for 7z format?

Rewriting file in the source 7z file directly is very difficult now.

I think what you have to do is to create a new 7z file, and then only decode the files that need to be modified in the src 7z file, and then write the modified content to the new file, and the other files in the src 7z file that do not need to be modified are directly written to the new 7z file.

But it's not supported now that reading the undecoded file content in the source 7z file or writing a encoded data into the new 7z file. I'll look at how to support this

oovm commented 1 year ago

This requirement is too rare, I just want to know if I can directly inplace rewrite.

If not, I tend to create different versions of the file and then provide a purge method to copy the used parts.

dyz1990 commented 1 year ago

@oovm I created a branch "7z_edit" that supported reading undecoded entry data from the SevenZReader and writing encoded data to the SevenZWriter. You can check the example in "examples/modify.rs" . I'm not sure if the example is working while the source 7z file was created by other programs.

oovm commented 1 year ago

Nice work, it works on bandizip LZMA2.