views:

80

answers:

2

I have the following code but it crashes every time it reaches the end of the function, but it successfully extracts all the files and puts them in the right location.

require "zip"

function ExtractZipAndCopyFiles(zipPath, zipFilename, destinationPath)
    local zfile, err = zip.open(zipPath .. zipFilename)

    -- iterate through each file insize the zip file
    for file in zfile:files() do
        local currFile, err = zfile:open(file.filename)
        local currFileContents = currFile:read("*a") -- read entire contents of current file
        local hBinaryOutput = io.open(destinationPath .. file.filename, "wb")

        -- write current file inside zip to a file outside zip
        if(hBinaryOutput)then
            hBinaryOutput:write(currFileContents)
            hBinaryOutput:close()
        end
    end

    zfile:close()
end
-- call the function
ExtractZipAndCopyFiles("C:\\Users\\bhannan\\Desktop\\LUA\\", "example.zip", "C:\\Users\\bhannan\\Desktop\\ZipExtractionOutput\\")

Why does it crash every time it reaches the end?

+2  A: 

Perhaps you need to call currFile:close() after currFile:read() in each iteration?

Doug Currie
Shouldn't the garbage collector take care of that?
Judge Maygarden
Doug Currie is absolutely correct. Please mark his answer as correct. I just tested it by inserting currFile:close() on a newline after the line that calls currFile:read() and now it works without crashing. What an eye, Doug! I'm purposefully commenting and not replying so that you can get the credit you deserve. Also, Brian, just as an FYI, as you probably know the code you have now won't unzip files inside folders in the zip file.
Pessimist
I do think it's a bit disappointing that this error isn't handled more gracefully. Crashing lua.exe is a little too much. If we didn't have Doug we'd be without a paddle to figure this out.
Pessimist
You should report the bug to the authors of the "zip" module you use.
Alexander Gladysh
So much for Lua being intuitive and easy for new programmers. I'm trying to find a programming language for non-programming testers (unlike myself) to easily create automated tests. Looks like I might have to look elsewhere.
Brian T Hannan
Thanks Doug, this worked.
Brian T Hannan
And as for folders inside of zip file, that won't be necessary for the job at hand.
Brian T Hannan
But ... if I wanted to do folders inside of zip how would I go about doing that? Is there an easy way to recurse through folders?
Brian T Hannan
@Brian: You probably picked bad module to work with zip files. There is a lot of them around: http://lua-users.org/wiki/CompressionAndArchiving
Alexander Gladysh
I'm looking for intuitiveness. luazip seems intuitive ... not some crazy-named module that is off in the distance somewhere.
Brian T Hannan
+2  A: 

The problem is that LuaZip does not iterate over all open internal files and close them before closing the open zip file in which they are contained. Thus, the system crashes later when the garbage collector attempts to close the internal files that have had the rug pulled out from under them. So, simply removing the zfile:close() line will also fix this crash because the garbage collector will release the userdata in reverse order of allocation.

I'd want to discuss possible solutions with Danilo, Andre and Tomas before submitting a patch because some design decisions need to be made. For example, if an internal file is open when client code closes the zip file do you keep the zip file open until all internal files are released or invalidate open references to each internal file? Perhaps it should be left alone and users should be instructed to either (a) let the garbage collector handle closing all internal and zip files or (b) explicitly close all internal files before closing the containing zip file.

Judge Maygarden
Personally, I'd say that you have to arrange things so that the GC doesn't cause the Windows abnormal termination dialog to appear, pretty much no matter what screwy thing your caller did to you.
RBerteig