Update: Dejay was correct, you have to try and open the file to know for sure if it’s there or not.
Want to know if a file exists before you use it?
Lately, I’ve been wanting something a little more dynamic in my projects for opening various Scenes (think Director, but not). I needed a way of looking to see if a file existed or not before I tried to load it up. Here’s the result:
function fileExists(fileName, base) assert(fileName, "fileName is missing") local base = base or system.ResourceDirectory local filePath = system.pathForFile( fileName, base ) local exists = false if (filePath) then -- file may exist. won't know until you open it local fileHandle = io.open( filePath, "r" ) if (fileHandle) then -- nil if no file found exists = true io.close(fileHandle) end end return(exists) end
Typical usage:
if fileExists("myGame.lua") then -- do something wonderful end
If the file does not exist, the CoronaSDK library function system.pathForFile()
returns nil
. It also returns a Warning in the console, which can be safely ignored.
By default it checks your app’s asset directory (system.ResourceDirectory), however, if you’d like to check if a file you created exists you can pass in an alternative base path like so:
if fileExists("some_file.txt", system.DocumentsDirectory) then -- do something wonderful end
The three valid options for base path are:
4 Comments
Isn’t it true that this approach won’t work for system.DocumentsDirectory and system.TemporaryDirectory? My understand is that because those directories are read/write, system.pathForFile will return true even if the file doesn’t exist, as long as the file COULD be created in those directories.
There are a few optimizations you could make to your code. First, system.pathForFile already uses system.ResourceDirectory as a default, so there’s no need to invoke “local base = base or system.ResourceDirectory”. Also, if base is set to system.ResourceDirectory, there’s no need to check to see if the file exists, because pathForFile already tells you that with read-only directories.
Thanks Dejay.
You’re right. I don’t need to do the “local base = base or …”, but I find it makes it easier for me to read later. I don’t have to know the defaults for pathForFile.
Also, if pathForFile returns nil (which it does for readonly directories), the code already exits without checking any further on Line 7.
Cheers.
Best explanation I found in the web!! Thank you so much