Почему после извлечения zip-файлов происходит сбой lua? - PullRequest
1 голос
/ 14 мая 2010

У меня есть следующий код, но он падает каждый раз, когда достигает конца функции, но успешно извлекает все файлы и помещает их в нужное место.

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\\")

Почему он падает каждый раз, когда достигает конца?

Ответы [ 2 ]

2 голосов
/ 14 мая 2010

Проблема в том, что LuaZip не выполняет итерацию по всем открытым внутренним файлам и не закрывает их перед закрытием открытого zip-файла, в котором они содержатся. Таким образом, система аварийно завершает работу, когда сборщик мусора пытается закрыть внутренние файлы, из-под которых извлечен коврик. Таким образом, простое удаление строки zfile:close() также исправит этот сбой, поскольку сборщик мусора выпустит userdata в обратном порядке распределения.

Я бы хотел обсудить возможные решения с Данило, Андре и Томасом перед тем, как отправлять патч, потому что нужно принять некоторые дизайнерские решения. Например, если внутренний файл открыт, когда код клиента закрывает zip-файл, оставляете ли вы zip-файл открытым до тех пор, пока не будут освобождены все внутренние файлы, или не аннулируете открытые ссылки на каждый внутренний файл? Возможно, его следует оставить в покое, а пользователей следует проинструктировать: (а) разрешить сборщику мусора закрывать все внутренние и zip-файлы или (b) явно закрыть все внутренние файлы перед закрытием содержащего zip-файла.

2 голосов
/ 14 мая 2010

Возможно, вам нужно вызывать currFile:close() после currFile:read() в каждой итерации?

...