QB64 Phoenix Edition
Making the content list of files inside a Zip ? - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Code and Stuff (https://qb64phoenix.com/forum/forumdisplay.php?fid=3)
+---- Forum: Help Me! (https://qb64phoenix.com/forum/forumdisplay.php?fid=10)
+---- Thread: Making the content list of files inside a Zip ? (/showthread.php?tid=2425)

Pages: 1 2


Making the content list of files inside a Zip ? - euklides - 02-05-2024

Well...
I'm looking for a way to list the files inside a zip file...

Than'ks for ideas.


RE: Making the content list of files inside a Zip ? - SpriggsySpriggs - 02-05-2024

https://devblogs.microsoft.com/scripting/powertip-use-powershell-to-read-the-content-of-a-zip-file/


RE: Making the content list of files inside a Zip ? - TerryRitchie - 02-05-2024

(02-05-2024, 03:21 PM)euklides Wrote: Well...
I'm looking for a way to list the files inside a zip file...

Than'ks for ideas.
I was playing around with 7Zip ( 7z.exe ) to see if I could get the results you want. The best I could get was this:

7z l -ba filename.zip

which lists output like this:

2014-08-21 00:37:55 ....A    1078326        45840    filename.ext
2014-08-22 10:19:59 ....A        13733                      anotherfile.txt
...
... etc..
...

You would need to parse out the information using code with this method of putting the listing into a file like so:

7z l -ba filename.zip > filelist.txt

However, I also found a batch file that strips everything except the file names themselves here:

https://stackoverflow.com/questions/55355466/7z-list-only-filenames

A full explanation of how the batch file works is included in the link above. Read the entire posting as others posted alternative methods using powershell scripts as well. Pick the one you like best.

Code: (Select All)
@Echo Off
  REM Sending the output of 7z into a file to use later
  7z.exe l -slt "SomeFileIZipped.zip" >"ZipListRAW.txt"
 
  REM Example of 7z.exe command with '-ba' switch
  REM 7z.exe l -ba -slt "SomeFileIZipped.zip"
 
  REM If you do not use '-ba' in the 7z command above, you can simply skip the first
  REM 11-12 lines of the file to get ONLY the filenames (skips past first line containing
  REM "Path" which contains the original archive filename.
 
  For /f "Usebackq Skip=11 Tokens=1,3* Delims= " %%a in ("ZipListRAW.txt") do (
    REM Checking if %%a equals word "Path"
    If "%%a"=="Path" (
      If [%%c]==[] (
        Echo %%b
      ) ELSE (
        Echo %%b %%c
      )
    )
  )
.


RE: Making the content list of files inside a Zip ? - bplus - 02-05-2024

How bout trying the new _files command and saving to file before you zip a folder?

before _files command I was taking a snapshot of folder in Windows Navigator to show (with GUI stuff) but you can't do sub-folders too well that way.


RE: Making the content list of files inside a Zip ? - a740g - 02-05-2024

I you want to read the zip central directory to get the files names programmatically (in a platform independent way), then you can use the APIs from libraries like zlib, miniz etc.

With a little bit of mixed language programming, it should be possible.


RE: Making the content list of files inside a Zip ? - visionmercer - 02-06-2024

This seems to work:
Code: (Select All)

Type ziphead
    signature As String * 4
    version As Integer
    flags As Integer
    compression As Integer
    modtime As Integer
    moddate As Integer
    crc_32 As Long
    compressedSize As Long
    uncompressedSize As Long
    filenameLen As Integer
    extrafieldLen As Integer
End Type

Dim i As Long
Dim filename As String
ReDim filelist(0) As String

filename = "yourfile.zip"
zipfilearray filename, filelist()
For i = 0 To UBound(filelist)
    Print Chr$(34); filelist(i); Chr$(34)
Next i

Sub zipfilearray (zipfile As String, strarr() As String)
    Dim head As ziphead
    Dim ff As Long
    Dim fname As String
    Dim filecount As Long
    ReDim strarr(0) As String
    If Not _FileExists(zipfile) Then Exit Sub
    ff = FreeFile
    Open zipfile For Binary As ff
    Do
        Get ff, , head
        If head.signature <> Chr$(&H50) + Chr$(&H4B) + Chr$(&H03) + Chr$(&H04) Then Exit Do
        fname = Space$(head.filenameLen)
        Get ff, , fname
        If filecount > UBound(strarr) Then ReDim _Preserve strarr(filecount) As String
        strarr(filecount) = fname
        filecount = filecount + 1
        Seek ff, Seek(ff) + head.extrafieldLen + head.compressedSize
    Loop Until EOF(ff)
End Sub



RE: Making the content list of files inside a Zip ? - euklides - 02-06-2024

Thank's for ideas and programs.

With 7z.exe , I knew this solution.
But I wanted a program working exclusively with QB64.

Visionmercer give the very good solution for this... 

Thank you all.


Smile


RE: Making the content list of files inside a Zip ? - TerryRitchie - 02-06-2024

Very cool @visionmercer

I hope you don't mind but I took the liberty of converting the subroutine to a function . The code also starts populating the array at index position 1 instead of 0.

I made a few minor changes in the function to streamline a bit and to close the file when finished.

By the way, this code only works with .ZIP files and not .7z files.

Code: (Select All)
DIM i AS LONG
DIM filename AS STRING
DIM filenumber AS LONG
REDIM filelist(0) AS STRING

filename = "test3.zip"
filenumber = zipfilearray(filename, filelist())
IF filenumber THEN

    PRINT "Total files found:"; filenumber
    PRINT
    FOR i = 1 TO filenumber
        PRINT CHR$(34); filelist(i); CHR$(34)
    NEXT i
ELSE
    PRINT "No files found or ZIP file does not exist."
END IF

FUNCTION zipfilearray (zipfile AS STRING, strarr() AS STRING)

    TYPE ziphead
        signature AS STRING * 4
        version AS INTEGER
        flags AS INTEGER
        compression AS INTEGER
        modtime AS INTEGER
        moddate AS INTEGER
        crc_32 AS LONG
        compressedSize AS LONG
        uncompressedSize AS LONG
        filenameLen AS INTEGER
        extrafieldLen AS INTEGER
    END TYPE

    DIM head AS ziphead
    DIM ff AS LONG
    DIM fname AS STRING
    DIM Sig AS STRING * 4

    REDIM strarr(0) AS STRING
    IF _FILEEXISTS(zipfile) THEN
        Sig = "PK" + CHR$(&H03) + CHR$(&H04) ' note: only works with .ZIP files
        ff = FREEFILE
        OPEN zipfile FOR BINARY AS ff
        DO
            GET ff, , head
            IF head.signature = Sig THEN
                fname = SPACE$(head.filenameLen)
                GET ff, , fname
                REDIM _PRESERVE strarr(UBOUND(strarr) + 1) AS STRING
                strarr(UBOUND(strarr)) = fname
                SEEK ff, SEEK(ff) + head.extrafieldLen + head.compressedSize
            END IF
        LOOP UNTIL EOF(ff) OR head.signature <> Sig
        CLOSE ff
    END IF
    zipfilearray = UBOUND(strarr)

END FUNCTION



RE: Making the content list of files inside a Zip ? - euklides - 02-06-2024

Thank's

And if you also want to know filesize:

    Do
        Get ff, , head
        If head.signature <> Chr$(&H50) + Chr$(&H4B) + Chr$(&H03) + Chr$(&H04) Then Exit Do
        fname = Space$(head.filenameLen)
        FX$ = Space$(head.uncompressedSize)
        Get ff, , fname
        If filecount > UBound(strarr) Then ReDim _Preserve strarr(filecount) As String
        strarr(filecount) = fname + "|" + _Trim$(Str$(Len(FX$)))
        filecount = filecount + 1
        Seek ff, Seek(ff) + head.extrafieldLen + head.compressedSize
    Loop Until EOF(ff)

And the program works with *.epub files  (that was my problem; epub are zip files)


RE: Making the content list of files inside a Zip ? - TerryRitchie - 02-06-2024

(02-06-2024, 05:04 PM)euklides Wrote: Thank's

And if you also want to know filesize:

    Do
        Get ff, , head
        If head.signature <> Chr$(&H50) + Chr$(&H4B) + Chr$(&H03) + Chr$(&H04) Then Exit Do
        fname = Space$(head.filenameLen)
        FX$ = Space$(head.uncompressedSize)
        Get ff, , fname
        If filecount > UBound(strarr) Then ReDim _Preserve strarr(filecount) As String
        strarr(filecount) = fname + "|" + _Trim$(Str$(Len(FX$)))
        filecount = filecount + 1
        Seek ff, Seek(ff) + head.extrafieldLen + head.compressedSize
    Loop Until EOF(ff)

And the program works with *.epub files  (that was my problem; epub are zip files)
Excellent addition.

A lot of file types are actually ZIP files in disguise. If the first two bytes of a file are 80 and 75 decimal, "PK", then the underlying data is more than likely a ZIP file in disguise.