Lua中如何检查文件是否存在

89

我如何使用Lua检查文件是否存在?


2
@tonio - 我猜你是指类似于http://www.lua.org/pil/21.2.html的内容。 - Mr. L
2
@Liutauras 这甚至接近一个真正的答案。我只是进行了一个快速检查。 - tonio
1
你好,感谢快速回复。我正在执行以下操作:assert(io.input(fileName), "Error opening file")但是当我提供一个虚拟文件名时,我没有收到错误消息:“Error opening file”。我收到的消息是:“bad argument #1 to 'input' (/pfrm2.0/share/lua/5.1/db/fake.dbdl: No such file or directory)”。有什么想法吗? - Yoni
1
你收到“bad argument#1 to 'input'”错误的原因是在Lua中,input只接受一个参数,而你传递了两个参数。此外,你应该使用assert io.open而不是input。 - Mr. L
1
没问题,Yoni。谢谢你整理好你的问题。现在它看起来更漂亮了。这不是为什么我们喜欢SO吗?因为它很棒。 - Mr. L
显示剩余4条评论
17个回答

125

尝试

function file_exists(name)
   local f=io.open(name,"r")
   if f~=nil then io.close(f) return true else return false end
end

但请注意,这段代码只是测试文件是否能够被打开以供读取。


4
注意:如果文件是目录,此方法返回false。 - QuidamAzerty

9

使用纯Lua,你最好的选择是按照LHF的建议检查文件是否可以被读取。这几乎总是足够的。但如果你需要更多的功能,请加载Lua POSIX库并检查posix.stat(路径)是否返回非nil值。


3
LuaFileSystem也适用于Windows操作系统。使用lfs.attributes(path,'mode')函数。 - Lorenzo Donati support Ukraine

7
Lua 5.1:
function file_exists(name)
   local f = io.open(name, "r")
   return f ~= nil and io.close(f)
end

7

我会引用自己在这里的内容:

我使用以下代码(但实际上我会检查错误):

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)命令可以将name1重命名为name2。如果两个名称相同,除非出现错误,否则不会发生任何更改。如果操作成功,则返回true;否则返回nil和错误信息。如果不想使用lfs,则无法区分文件和目录,除非尝试打开该文件(这可能有点慢,但还算可以)。

因此,在没有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

看起来更短,但需要更长时间... 同时打开文件也有一定的风险

愉快地进行编码吧!


2
关于重命名只读文件,如何处理os.rename引发的错误? - Henrik Erlandsson
仅仅从Lua中打开文件有哪些风险? - carpii
@carpii 如果您尝试打开一个被锁定的文件并从中读取,可能会导致错误(您仍然想知道它是文件还是其他类型)。对于目录也是如此(如果主机支持目录锁定)。 - tDwtp
@HenrikErlandsson 你是什么意思?我所说的“badass error”并不是指可以通过代码修复的问题。然而,据我所知,你可以使用pcall来捕获这些错误。处理可能会很复杂,并且可能返回不够详细的错误信息。 - tDwtp

6

如果您正在使用 Premake 和 LUA 版本 5.3.4:

if os.isfile(path) then
    ...
end

2
这不是官方功能,而是Premake的功能。 - Konrad
1
@Konrad AH。我的错误。premake是我使用lua的全部。:( - Jesse Chisholm
没问题,伙计。 - Konrad

4
如果您愿意使用lfs,可以使用lfs.attributes。它将在出错的情况下返回nil
require "lfs"

if lfs.attributes("non-existing-file") then
    print("File exists")
else
    print("Could not get attributes")
end

虽然它可能会对存在的文件以外的其他错误返回 nil,但如果没有返回 nil,则该文件肯定存在。


3

为了完整起见:您也可以尝试运行 path.exists(filename)。我不确定哪些Lua发行版实际上具有此path命名空间(更新Penlight),但至少在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) 告诉我它的源代码在 torch/install/share/lua/5.1/pl/path.lua 中,实现方式如下:

--- 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

1
那将是Penlight,它在幕后使用LuaFileSystem - siffiejoe

3

一个仅适用于Windows的答案检查文件和文件夹,也不需要额外的软件包。它将返回truefalse

io.popen("if exist "..PathToFileOrFolder.." (echo 1)"):read'*l'=='1'

io.popen(...):read'*l' - 在命令提示符中执行命令并从CMD标准输出读取结果

if exist - CMD命令用于检查对象是否存在

(echo 1) - 将1打印到命令提示符的标准输出


这会打开一个短暂可见的控制台窗口,所以我建议不要这么做。 - ZzZombo

2

一个仅适用于Windows的答案检查文件和文件夹,并且不需要额外的软件包。它返回真或假。


1
你也可以使用“paths”包。这里是该包的链接。
然后在Lua中执行:
require 'paths'

if paths.filep('your_desired_file_path') then
    print 'it exists'
else
    print 'it does not exist'
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接