How can I check if a file exists using Lua?
-
1@Mitch as in http://stackoverflow.com/questions/1340230/check-if-directory-exists-in-lua ? – tonio Feb 14 '11 at 10:24
-
2@tonio - I guess more as in http://www.lua.org/pil/21.2.html – Mr. L Feb 14 '11 at 10:27
-
2@Liutauras that is even close to a real answer. I only did a quick check only on so – tonio Feb 14 '11 at 10:45
-
1Hi, Thx for the quick respond. I am doing: assert(io.input(fileName), "Error opening file") But when i give a dummy filename, i don't get the error message : "Error opening file". The message i get is: "bad argument #1 to 'input' (/pfrm2.0/share/lua/5.1/db/fake.dbdl: No such file or directory)" any thoughts ? – Yoni Feb 14 '11 at 13:21
-
1Yoni, I understand you just joined SO. Welcome. Few things to mention. 1) Don't answer your own question with a new question. 2) Try to search around (Google is your friend) for more info and only if you are completely stuck ask here. This I believe will make you a better developer. – Mr. L Feb 14 '11 at 13:21
-
1The reason you get "bad argument#1 to 'input'" is that input in Lua only takes one argument and you are passing 2. Plus you should assert io.open not input. – Mr. L Feb 14 '11 at 13:21
-
1Hi Liutauras, i will take more notice for next time, sorry for that. – Yoni Feb 14 '11 at 13:21
-
1Also, i've change to io.open and it works now. Thank you – Yoni Feb 14 '11 at 13:21
-
1No problem Yoni. Thanks for sorting out your question. It just looks nicer now. Isn't why we love SO. Because it's nice. – Mr. L Feb 14 '11 at 13:51
17 Answers
Try
function file_exists(name)
local f=io.open(name,"r")
if f~=nil then io.close(f) return true else return false end
end
but note that this code only tests whether the file can be opened for reading.

- 70,581
- 9
- 108
- 149
Using plain Lua, the best you can do is see if a file can be opened for read, as per LHF. This is almost always good enough. But if you want more, load the Lua POSIX library and check if posix.stat(
path)
returns non-nil
.

- 198,648
- 61
- 360
- 533
-
3[LuaFileSystem](http://keplerproject.github.io/luafilesystem) works on Windows too. Use `lfs.attributes(path,'mode')` – LorenzoDonati4Ukraine-OnStrike Aug 20 '13 at 16:15
Lua 5.1:
function file_exists(name)
local f = io.open(name, "r")
return f ~= nil and io.close(f)
end

- 19,527
- 31
- 134
- 226
I will quote myself from here
I use these (but I actually check for the error):
require("lfs")
-- no function checks for errors.
-- you should check for them
function isFile(name)
if type(name)~="string" then return false end
if not isDir(name) then
return os.rename(name,name) and true or false
-- note that the short evaluation is to
-- return false instead of a possible nil
end
return false
end
function isFileOrDir(name)
if type(name)~="string" then return false end
return os.rename(name, name) and true or false
end
function isDir(name)
if type(name)~="string" then return false end
local cd = lfs.currentdir()
local is = lfs.chdir(name) and true or false
lfs.chdir(cd)
return is
end
os.rename(name1, name2) will rename name1 to name2. Use the same name and nothing should change (except there is a badass error). If everything worked out good it returns true, else it returns nil and the errormessage. If you dont want to use lfs you cant differentiate between files and directories without trying to open the file (which is a bit slow but ok).
So without LuaFileSystem
-- no require("lfs")
function exists(name)
if type(name)~="string" then return false end
return os.rename(name,name) and true or false
end
function isFile(name)
if type(name)~="string" then return false end
if not exists(name) then return false end
local f = io.open(name)
if f then
f:close()
return true
end
return false
end
function isDir(name)
return (exists(name) and not isFile(name))
end
It looks shorter, but takes longer... Also open a file is a it risky
Have fun coding!
-
2How are errors from os.rename handled regarding renaming read-only files? – Henrik Erlandsson Aug 20 '14 at 06:30
-
-
@carpii If you try to open a locked file and read from it it may result in an error (you still want to know whether its a file or not). Same goes for directories (if diectory lock is supported on the host). – tDwtp Jul 23 '15 at 02:58
-
@HenrikErlandsson What do you mean? With 'badass error' i did not mean something you could fix by code. However, AFAIK you can use pcall to capture them. Handling might be complicated and uninformative error messages could be returned. – tDwtp Jul 23 '15 at 03:02
If you're using Premake and LUA version 5.3.4:
if os.isfile(path) then
...
end

- 2,885
- 2
- 23
- 27

- 3,857
- 1
- 35
- 29
For sake of completeness: You may also just try your luck with path.exists(filename)
. I'm not sure which Lua distributions actually have this path
namespace (update: Penlight), but at least it is included in Torch:
$ th
______ __ | Torch7
/_ __/__ ________/ / | Scientific computing for Lua.
/ / / _ \/ __/ __/ _ \ | Type ? for help
/_/ \___/_/ \__/_//_/ | https://github.com/torch
| http://torch.ch
th> path.exists(".gitignore")
.gitignore
th> path.exists("non-existing")
false
debug.getinfo(path.exists)
tells me that its source is in torch/install/share/lua/5.1/pl/path.lua
and it is implemented as follows:
--- does a path exist?.
-- @string P A file path
-- @return the file path if it exists, nil otherwise
function path.exists(P)
assert_string(1,P)
return attrib(P,'mode') ~= nil and P
end

- 23,414
- 14
- 122
- 178
-
1That would be [Penlight](https://github.com/stevedonovan/Penlight/blob/master/lua/pl/path.lua), and it uses [LuaFileSystem](http://keplerproject.github.io/luafilesystem/) behind the scenes. – siffiejoe Oct 12 '15 at 12:00
If you are willing to use lfs
, you can use lfs.attributes
. It will return nil
in case of error:
require "lfs"
if lfs.attributes("non-existing-file") then
print("File exists")
else
print("Could not get attributes")
end
Although it can return nil
for other errors other than a non-existing file, if it doesn't return nil
, the file certainly exists.

- 1,664
- 1
- 20
- 30
An answer which is windows only checks for files and folders, and also requires no additional packages. It returns true
or false
.
io.popen("if exist "..PathToFileOrFolder.." (echo 1)"):read'*l'=='1'
io.popen(...):read'*l' - executes a command in the command prompt and reads the result from the CMD stdout
if exist - CMD command to check if an object exists
(echo 1) - prints 1 to stdout of the command prompt

- 301
- 2
- 8
-
This opens a briefly visible console window, so I'd advise against this idea. – ZzZombo Jan 08 '21 at 18:01
An answer which is windows only checks for files and folders, and also requires no additional packages. It returns true or false.

- 29
- 2
Not necessarily the most ideal as I do not know your specific purpose for this or if you have a desired implementation in mind, but you can simply open the file to check for its existence.
local function file_exists(filename)
local file = io.open(filename, "r")
if (file) then
-- Obviously close the file if it did successfully open.
file:close()
return true
end
return false
end
io.open
returns nil
if it fails to open the file. As a side note, this is why it is often used with assert
to produce a helpful error message if it is unable to open the given file. For instance:
local file = assert(io.open("hello.txt"))
If the file hello.txt
does not exist, you should get an error similar to stdin:1: hello.txt: No such file or directory
.

- 464
- 4
- 13
For library solution, you can use either paths
or path
.
From the official document of paths
:
paths.filep(path)
Return a boolean indicating whether path refers to an existing file.
paths.dirp(path)
Return a boolean indicating whether path refers to an existing directory.
Although the names are a little bit strange, you can certainly use paths.filep()
to check whether a path exists and it is a file. Use paths.dirp()
to check whether it exists and it is a directory. Very convenient.
If you prefer path
rather than paths
, you can use path.exists()
with assert()
to check the existence of a path, getting its value at the same time. Useful when you are building up path from pieces.
prefix = 'some dir'
filename = assert(path.exist(path.join(prefix, 'data.csv')), 'data.csv does not exist!')
If you just want to check the boolean result, use path.isdir()
and path.isfile()
. Their purposes are well-understood from their names.
How about doing something like this?
function exist(file)
local isExist = io.popen(
'[[ -e '.. tostring(file) ..' ]] && { echo "true"; }')
local isIt = isExist:read("*a")
isExist:close()
isIt = string.gsub(isIt, '^%s*(.-)%s*$', '%1')
if isIt == "true" then
return true
end
return false
end
if exist("myfile") then
print("hi, file exists")
else
print("bye, file does not exist")
end

- 377
- 4
- 15

- 473
- 8
- 13
-
I get `'[[' is not recognized as an internal or external command, operable program or batch file.` – sdbbs Sep 02 '20 at 15:18
-
Its working on my unix machine. What OS are you using ? `type [[` should say `[[ is a shell keyword` – Rakib Fiha Sep 02 '20 at 16:42
-
1@RakibFiha he using windows based on the error message and it work on my Linux machine – Blanket Fox Jul 04 '21 at 07:03
If you use LOVE, you can use the function love.filesystem.exists('NameOfFile')
, replacing NameOfFile
with the file name.
This returns a Boolean value.

- 75
- 7
if you are like me exclusively on Linux, BSD any UNIX type you can use this:
function isDir(name)
if type(name)~="string" then return false end
return os.execute('if [ -d "'..name..'" ]; then exit 0; else exit 1; fi')
end
function isFile(name)
if type(name)~="string" then return false end
return os.execute('if [ -f "'..name..'" ]; then exit 0; else exit 1; fi')
end
Actually this looks even better:
function isDir(name)
if type(name)~="string" then return false end
return os.execute('test -d '..name)
end
function isFile(name)
if type(name)~="string" then return false end
return os.execute('test -f '..name)
end
function exists(name)
if type(name)~="string" then return false end
return os.execute('test -e '..name)
end

- 3,474
- 2
- 39
- 43
Lua 5.4:
function file_exists(name)
local f <close> = io.open(name, "r")
return f ~= nil
end
IsFile = function(path)
print(io.open(path or '','r')~=nil and 'File exists' or 'No file exists on this path: '..(path=='' and 'empty path entered!' or (path or 'arg "path" wasn\'t define to function call!')))
end
IsFile()
IsFile('')
IsFIle('C:/Users/testuser/testfile.txt')
Looks good for testing your way. :)

- 171
- 1
- 12