Recursively Deleting Subdirectories and Subfiles

In my project, I’m trying to delete a folder, including all of its subdirectories and subfiles. I found some previous code in the Corona Forums, which made use of LFS and os.remove(). However, for some reason, the code can only delete the subfiles, but NOT the subdirectories. For the subdirectories, the reason that Corona gives for failure is PERMISSION DENIED. I am at a loss at why the code is deleting only the files, but not the subfolders?

Here’s the code: The code assumes that there is a folder in the Documents directory called folder1. Under folder1, I just added a bunch of subfolders and subfiles.

local title = display.newText("DELETE", display.contentCenterX, display.contentCenterY - 100 + 15, native.systemFont, 20 ) local function deleteDirectory(dir)     local resultOK, errorMsg;              --remove files from directory     for file in lfs.dir(dir) do         if ((file == ".") or (file == "..")) then -- skip system files             -- do nothing         else             local theFile = dir.."/"..file;             if (lfs.attributes(theFile, "mode") == "directory") then                 deleteDirectory(theFile);             else                 resultOK, errorMsg = os.remove(theFile);                 if (not resultOK) then                     print("Error removing file: "..file..":"..errorMsg);                 else print("Removed file: " .. file)                 end             end         end     end     -- remove directory     resultOK, errorMsg = os.remove(dir);     if (not resultOK) then         print("Error removing directory: "..dir.."---\>\>\>"..errorMsg);         else print("Removed directory: " .. dir)     end end local function delete()     deleteDirectory(system.pathForFile("folder1", system.DocumentsDirectory)) end title:addEventListener("tap", delete)

Edit: The code is copy & pastable

I think I might have found the problem. According to this stack overflow thread (http://stackoverflow.com/questions/29532422/lua-os-remove-folder-results-in-permission-denied), the os.remove command may misbehave on Windows OS.

The os.remove documentation states:

Deletes the file (or empty directory, on POSIX systems) with the given name. If this function fails, it returns nil , plus a string describing the error and the error code.

Windows is not POSIX compliant OS, therefore; exhibiting such a behaviour.

To get POSIX compatibility in Windows 7, you have to activate the Subsystem for UNIX-based applications (SUA / Interix) in Windows.

Is activating the subsystem for unix the only solution for Windows? Even if it is the solution, will the application still run properly on Android and iPhone without enabling additional settings?

  1. You may run into trouble removing any folder if you’ve been using the files in it during that app/game session.  i.e. If a file is open, you can’t delete it or the folder it is in.

  2. I’d use GGFile instead of the code you found.  Their library/module is very easy to use and reliable:

http://github.com/GlitchGames/GGFile

@roaminggamer

  1. I thought this was the case too, because trying to delete an open file has in the past caused me problems. However, I can assure you this isn’t the case this time. I manually created the subfiles and subfolders in the DocumentsDirectory and ensured that they weren’t open nor was the application using it. I’m pretty sure it’s the POSIX compliance problem. Can someone with a MAC run the code to confirm this?

  2. Thanks for the suggestion! I’ll try it soon, and see if it works.

I tried the GGFile module, and after a little experimenting, I got it to work. The main difference was that the code in GGFile used lfs.rmdir() instead of os.remove() to remove a directory, which allows it to work on Windows devices. Here’s the code for anyone who’s interested. It should be pretty self explanatory. (Of course it assumes you have the GGFiles module http://github.com/GlitchGames/GGFile)

local GGFile = require( "GGFile" ) local fileManager = GGFile:new() local function deleteDirectory(curDir, baseDir) local files = fileManager:getFilesInDirectory(curDir, baseDir) for i = 1, #files, 1 do local file = curDir .. "/" .. files[i] if (fileManager:isDirectory(file, baseDir)) then --Is Directory (Recursive Call) deleteDirectory(file) else --Is File fileManager:delete(file, baseDir) end end --Delete current directory after taking care of its contents local success, reason = fileManager:removeDirectory( curDir, baseDir) print( success, reason ) end deleteDirectory("folder1", system.DocumentsDirectory)

I think I might have found the problem. According to this stack overflow thread (http://stackoverflow.com/questions/29532422/lua-os-remove-folder-results-in-permission-denied), the os.remove command may misbehave on Windows OS.

The os.remove documentation states:

Deletes the file (or empty directory, on POSIX systems) with the given name. If this function fails, it returns nil , plus a string describing the error and the error code.

Windows is not POSIX compliant OS, therefore; exhibiting such a behaviour.

To get POSIX compatibility in Windows 7, you have to activate the Subsystem for UNIX-based applications (SUA / Interix) in Windows.

Is activating the subsystem for unix the only solution for Windows? Even if it is the solution, will the application still run properly on Android and iPhone without enabling additional settings?

  1. You may run into trouble removing any folder if you’ve been using the files in it during that app/game session.  i.e. If a file is open, you can’t delete it or the folder it is in.

  2. I’d use GGFile instead of the code you found.  Their library/module is very easy to use and reliable:

http://github.com/GlitchGames/GGFile

@roaminggamer

  1. I thought this was the case too, because trying to delete an open file has in the past caused me problems. However, I can assure you this isn’t the case this time. I manually created the subfiles and subfolders in the DocumentsDirectory and ensured that they weren’t open nor was the application using it. I’m pretty sure it’s the POSIX compliance problem. Can someone with a MAC run the code to confirm this?

  2. Thanks for the suggestion! I’ll try it soon, and see if it works.

I tried the GGFile module, and after a little experimenting, I got it to work. The main difference was that the code in GGFile used lfs.rmdir() instead of os.remove() to remove a directory, which allows it to work on Windows devices. Here’s the code for anyone who’s interested. It should be pretty self explanatory. (Of course it assumes you have the GGFiles module http://github.com/GlitchGames/GGFile)

local GGFile = require( "GGFile" ) local fileManager = GGFile:new() local function deleteDirectory(curDir, baseDir) local files = fileManager:getFilesInDirectory(curDir, baseDir) for i = 1, #files, 1 do local file = curDir .. "/" .. files[i] if (fileManager:isDirectory(file, baseDir)) then --Is Directory (Recursive Call) deleteDirectory(file) else --Is File fileManager:delete(file, baseDir) end end --Delete current directory after taking care of its contents local success, reason = fileManager:removeDirectory( curDir, baseDir) print( success, reason ) end deleteDirectory("folder1", system.DocumentsDirectory)