Can't delete image file in Documents directory

In our games we have a “camera” that allows players to take photos of clues, i.e. screenshots, these are then saved to the Documents directory. These photos can later be deleted by the player. This works great on iOS, Android, and Mac OSX, however it doesn’t work on Windows. 

This can be reproduced with this code ( you’ll need to put an image called “original.png” in the root with main.lua ) :

--Load up an image local original = display.newImage( "original.png" ) original.x = display.contentCenterX original.y = display.contentCenterY -- Save it out display.save( original, "copy.png" ) -- Destroy the image object display.remove( original ) original = nil -- Load up the copy local copy = display.newImage( "copy.png", system.DocumentsDirectory ) copy.x = display.contentCenterX copy.y = display.contentCenterY + 100 -- Destroy the copy display.remove( copy ) copy = nil -- Try to delete it local result, reason = os.remove( system.pathForFile( "copy.png", system.DocumentsDirectory ) ) -- This will most likely fail and have permission denied error print( result, reason)

I’m assuming the permission is denied because something is still holding onto the image file? Or is this a permission I need to give our apps to allow this to work on Windows?

Loading the image file via display.newImage() is causing the file to be locked that’s preventing it from being deleted.  The Windows file system is much more aggressive about locking files than the Unix’y file systems that OS X, iOS, and Android uses.  And event though you are removing the object just after, I don’t think Corona will actually let go of the image file internally until 1-3 frames later in case you load the same image again later for performance reasons.  Admittedly, we’re probably being a bit aggressive about that on our end too, but that’s how it is at the moment.  So, yeah, you can either avoid loading the captured image you intend to delete or set up a one shot timer to delete the capture image file later.

Hmm I thought I tried adding a delay and it still had issues, I’ll try again now. Maybe it solved the issue but caused another, will have to check. 

I’m guessing to make it less aggressive would be a relatively large change so we shouldn’t wait for that? This is the only thing holding us back from releasing on Windows.

>> I’m guessing to make it less aggressive would be a relatively large change so we shouldn’t wait for that?

More like it will have a bigger impact on performance.  It is something we can evaluate in the future, but I wouldn’t wait for it.  Our current priority is to get Corona for Windows near the same feature level as it is on OS X.

OK that’s fair. 

I’ll try the delay again and see if I can get it working. Thanks for the help!

Hey… perhaps a better solution would be for you to use our display.capture*() APIs instead?

Those APIs do capture just like display.save(), but instead of saving it to file, they store the capture image to memory and immediately display it as a display object.  And you can also display.save() the returned capture display object if you need it for later use.  Just an idea.

Sadly I’m not sure if that could work in our scenario.

We allow the player to take photos of basically everything, these can then be pulled up at any other time in the game as well as deleted anytime they want. So at somepoint in the game they;ll load up the photoalbum, which loads up a few of the photos into view, and then they can choose to delete one then.

I think if it could work with the capture apis then it might end up being quite a bit of a change and as it’s working fine on everything but windows, I think I’ll just go for the delay method for now.

By adding a very short delay between the destruction of the display object and the actual removing of the image seems to have fixed this.

Loading the image file via display.newImage() is causing the file to be locked that’s preventing it from being deleted.  The Windows file system is much more aggressive about locking files than the Unix’y file systems that OS X, iOS, and Android uses.  And event though you are removing the object just after, I don’t think Corona will actually let go of the image file internally until 1-3 frames later in case you load the same image again later for performance reasons.  Admittedly, we’re probably being a bit aggressive about that on our end too, but that’s how it is at the moment.  So, yeah, you can either avoid loading the captured image you intend to delete or set up a one shot timer to delete the capture image file later.

Hmm I thought I tried adding a delay and it still had issues, I’ll try again now. Maybe it solved the issue but caused another, will have to check. 

I’m guessing to make it less aggressive would be a relatively large change so we shouldn’t wait for that? This is the only thing holding us back from releasing on Windows.

>> I’m guessing to make it less aggressive would be a relatively large change so we shouldn’t wait for that?

More like it will have a bigger impact on performance.  It is something we can evaluate in the future, but I wouldn’t wait for it.  Our current priority is to get Corona for Windows near the same feature level as it is on OS X.

OK that’s fair. 

I’ll try the delay again and see if I can get it working. Thanks for the help!

Hey… perhaps a better solution would be for you to use our display.capture*() APIs instead?

Those APIs do capture just like display.save(), but instead of saving it to file, they store the capture image to memory and immediately display it as a display object.  And you can also display.save() the returned capture display object if you need it for later use.  Just an idea.

Sadly I’m not sure if that could work in our scenario.

We allow the player to take photos of basically everything, these can then be pulled up at any other time in the game as well as deleted anytime they want. So at somepoint in the game they;ll load up the photoalbum, which loads up a few of the photos into view, and then they can choose to delete one then.

I think if it could work with the capture apis then it might end up being quite a bit of a change and as it’s working fine on everything but windows, I think I’ll just go for the delay method for now.

By adding a very short delay between the destruction of the display object and the actual removing of the image seems to have fixed this.