4
\$\begingroup\$

I have written a script that run in WingFTP Server which has a Lua scripting engine built in. The script recursively deletes empty folders except the specified root folder.

--Walks a file tree and delete empty folders except the root folder
function EmptyFolderDeleter(options)
    local rootPath = options.path
    local path = options.path

    function walk(path)
        local currentPath = path

        --cycle through the current directory, walking directories
        for dir in c_GetDir(currentPath) do
            local fullPath = currentPath..dir.."/"
            walk(fullPath)
        end

        --if we've got this far then we're at the bottom of the tree
        --there are no more directories to visit
        --now check if there is ANYTHING (file or folder) in the current folder 
        local empty = true
        for isdir, file in c_GetFileDir(currentPath) do
            empty = false
        end

        --now check the 'empty' flag and if the folder is the root
        if empty == true and currentPath ~= rootPath then
            c_RemoveFileDir(currentPath)
        end

    end
    walk(path)
 end

The script uses three custom Lua functions that are built into WingFTP:

c_GetDir() = an iterator that returns directory names as string

c_GetFileDir() = an iterator that returns directory and file names as strings. Also returns a boolean whether the returned string is directory or not.

c_RemoveFileDir() = Deletes the specified file or folder

My script can be called like so like so:

local root = "D:/Clients/"
for dir in c_GetDir(root) do
    EmptyFolderDeleter{path=root..dir.."/"}
end

Is there is simpler or more efficient way to recursively delete empty sub folders in Lua?

Is there anything I can do to improve code readability?

\$\endgroup\$
3
\$\begingroup\$

Since you're not updating the variables path, rootPath and currentPath anywhere, use a single variable.

Define the function walk locally.

You can also break out of your c_GetFileDir loop once you've updated the empty flag. This will remove the time to iterate through all children of a directory.

The help pages for WFTPServer have a different return values for c_GetFileDir than yours!

function EmptyFolderDeleter( options )
    local root = options.path

    local walk = function( path )

        --cycle through the current directory, walking directories
        for dir in c_GetDir( path ) do
            walk( path..dir.."/" )
        end

        --if we've got this far then we're at the bottom of the tree
        --there are no more directories to visit
        --now check if there is ANYTHING (file or folder) in the current folder 
        local empty = true
        for isdir, file in c_GetFileDir( path ) do
            empty = false
            break
        end

        --now check the 'empty' flag and if the folder is the root
        if empty and path ~= root then
            c_RemoveFileDir( path )
        end
    end

    walk( root )
 end
| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ Regarding c_GetFileDir in the help pages: Yes I was scratching my head for ages and then I contacted WingFTP directly who confirmed that their help pages are in fact incorrect! \$\endgroup\$ – chazjn May 11 '15 at 14:49
  • \$\begingroup\$ Thanks for your tips, I feel the readability of the code has been improved. Just one note: I like the the white spacing in the function parameters, e.g. walk( root ) I have not seen this before and am surprised that I quite like it! How do you format functions with multiple parameters? \$\endgroup\$ – chazjn May 12 '15 at 7:29
  • 1
    \$\begingroup\$ @chazjn f( a, b, {1, 2, 3}, c, d ) \$\endgroup\$ – hjpotter92 May 12 '15 at 11:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.