This topic contains 2 replies, has 2 voices, and was last updated by  Sandeep 3 months, 3 weeks ago.

Zip multiple files in a folder

  • Hi,

    I have multiple files in a folder and I want to zip them using a channel. I tried this code but when I try to reopen the zip, it says it is invalid.

    function main()
    local fa = io.open(‘D:\\CDGE\\Leave_20190430163156.csv’, ‘r’)
    local fb = io.open(‘D:\\CDGE\\TimeClock_20190430163233.csv’, ‘r’)

    — construct table to zip using file content
    — NOTE: We also added an (empty) subdirectory ‘test_sub’
    local TT = {[‘test_zip2’]={[‘a-test.csv’]=fa:read(), [‘b-test.csv’]=fb:read(‘*a’)}}
    trace(TT)

    — zip the file into a string
    local zip = filter.zip.deflate(TT)
    trace(zip)

    — save the second zip file to disk
    local f = io.open(‘D:\\test_zip2.zip’, ‘w’)
    f:write(zip)
    f:close()
    end

    Is there any other approach where I can just provide the path and channel will zip all the files in that folder.

    This is a case where recursion is a good concept to understand, since you’ll need to recurse through the path tree to get every file (and the associated path to it) that you want in your resulting zip file.

    Fortunately for you, I’ve written a Lua library that does just that:

    local zip = require('zipit')
    
    function main(Data)
       local filePath = 'C:\\Test\\'
       local filePtrn = '.hl7$' -- uses Lua pattern match for filenames, not glob
       local zipFile  = 'c:\\temp\\ziptemp.zip'
       local zipped   = zip:createZip{path=filePath,pat=filePtrn,zipfile=zipFile}
       iguana.logInfo("Files compressed:\r\n\r\n" .. table.concat(zipped,"\r\n"))
    end
    

    Library zipit.lua is listed below. I tried to upload it as an attachment, but apparently Lua files aren’t allowed 😀

    Use at your own risk, of course.

    -- Created 2019-04-14 by Jeff Drumm, HICG LLC | http://www.hicgrp.net
    -- Use at your own risk. No warranties expressed or implied.
    local zipit = {}
    
    zipit.origPathLen = 0
    
    function zipit.createZip(self,tbl)
       tbl.path          = tbl.path:gsub('\\','/')
       tbl.path          = table.concat(tbl.path:split('/'),'/'):gsub('/$','')
       self.origPathLen  = tbl.path:len() + 2
       local glob        = tbl.path .. '/*'
       if not tbl.pat then tbl.pat = '.*' end
       local fileAry     = {}
       local zipTbl      = self:buildZipTbl{path=glob, pat=tbl.pat, ftable={}}
       -- binary mode req'd on Windows; doesn't hurt on *nix
       local zh          = io.open(tbl.zipfile,"wb")
       zh:write(filter.zip.deflate(zipTbl))
       zh:close()
       for key in pairs(zipTbl) do
          table.insert(fileAry,key)
       end
       return fileAry
    end
    
    function zipit.buildZipTbl(self,tbl)
       for name,stat in os.fs.glob(tbl.path) do
          if stat.isdir then
             self:buildZipTbl{path=name..'/*', pat=tbl.pat, ftable=tbl.ftable}
          else
             if name:find(tbl.pat) then
                -- binary mode requ'd on Windows; doesn't hurt on *nix
                local fh    = io.open(name,"rb")
                local data  = fh:read('*a')
                fh:close()
                -- only seems to work correctly if you change the name to a relative path
                -- also remove drive letter if present
                local fname = name:sub(self.origPathLen,-1)
                trace(fname)
                --local fname = name:gsub('^%a?:?/*','')
                tbl.ftable[fname] = data
             end
          end
       end
       return tbl.ftable
    end
    
    local zipit_createZip = {}
    zipit_createZip.Title='zipit.createZip'
    zipit_createZip.ParameterTable=true
    zipit_createZip.Usage='createZip{path=file_path,pat=file_pattern,zipfile=destination_file}'
    zipit_createZip.Parameters={
       {path={Desc='Base path to file location'}},
       {pat={Desc='Lua pattern for file match'}},
       {zipfile={Desc='path to output zip file'}}}
    zipit_createZip.Examples={'local zip = require(zipit)\r\n\r\nlocal zipTbl = zip:createZip(path="C:\\\\output\\\\",pat="hl7$",zipfile="C:\\\\archive\\\\output.zip"'}
    zipit_createZip.Returns={{Desc='A list containing the names of the compressed files'}}
    
    
    help.set{input_function=zipit.createZip,help_data=zipit_createZip}
    
    return zipit
    

    Jeff Drumm ◊ VP and COO ◊ HICG, LLC. ◊ http://www.hicgrp.com

    Hi Jeff,

    It worked like a charm. Thank you so much!!!

    Thank you again.

Tagged: 

You must be logged in to reply to this topic.