wqweto / ZipArchive

A single-class pure VB6 library for zip with ASM speed
MIT License
52 stars 22 forks source link

Unzip a file from subfolder of zip, in a folder without subfolder #21

Closed CouinCouin closed 1 year ago

CouinCouin commented 1 year ago

Hi wqweto,

Trying to run your app :) Successfully ziped the 3 example files from C:\TEMP (replaces D:\TEMP as well as on the VM I have only C:\ ) to aaa.zip (removed level in the zip filename), with Command_3 sub. So the aaa.zip has inside:

mem/enwik8.txt
mem/report.pdf
mem/report2.pdf
mem/thunk.bin

Now trying to extract a file (for example mem/report2.pdf) to C:\TEMP\Unzip but without creating the "mem" subfolder. The goal is to get C:\TEMP\Unzip\report.pdf .

Tried Command_4 sub, where I changed bResult for : .bResult = .Extract ("C:\TEMP\Unzip\", "mem/report2.pdf"

I get nothing.

Commented the lines :

Set m_oExtractInMemory = m_oZip
Set m_oExtractInMemory = Nothing

I get file extracted but it is here C:\TEMP\Unzip\mem\report.pdf

Is there a way to ride of the "mem" subfolder ?

Thanks :) Couin

wqweto commented 1 year ago

Command3 is example of using in-memory operations with the memory stream class provided.

You can compress a file under a different name in the archive using the (optional) second parameter of AddFile method like this:

    With New cZipArchive
        .AddFile "D:\TEMP\aaa.pdf", "mem/report.pdf"
        .CompressArchive "D:\TEMP\aaa.zip"
    End With

This way aaa.pdf file on disk is stored as report.pdf entry in mem directory in the archive.

If you want to extract report.pdf to a custom folder on disk you can either use in-memory operations (i.e. extract to a byte-array and save it to whatever target file you want) or implement BeforeExtract event and modify File parameter like this:

Private WithEvents m_oExtractRename As cZipArchive

Private Sub Command8_Click()
    Set m_oExtractRename = New cZipArchive
    With m_oExtractRename
        .OpenArchive "D:\TEMP\aaa.zip"
        .Extract "D:\Temp"
    End With
End Sub

Private Sub m_oExtractRename_BeforeExtract(ByVal FileIdx As Long, File As Variant, SkipFile As Boolean, Cancel As Boolean)
    '--- change output path to D:\Temp
    File = "D:\Temp\" & Mid$(File, InStrRev(File, "\") + 1)
End Sub

Edit: Using in-memory operations is probably the easiest with something like this:

    Dim baOutput() As Byte
    With New cZipArchive
        .OpenArchive "D:\TEMP\aaa.zip"
        .Extract baOutput, "mem/report.pdf"
        WriteBinaryFile "D:\Temp\report.pdf", baOutput
    End With
CouinCouin commented 1 year ago

Hi wqweto,

Thanks a lot, just quicky tried with the solution from your "Edit" and look working like desired :)

And yes, it's seems to be the best method, as well ad target folder can be different between files from inside the zip archive.

See ya :)