Lua中如何检查目录是否存在?

如何在Lua中检查目录是否存在,最好不使用LuaFileSystem模块?

尝试像这样使用Python代码:

os.path.isdir(path)

原文链接 https://stackoverflow.com/questions/1340230

点赞
stackoverflow用户126042
stackoverflow用户126042

好的,5.1参考手册在 os表 没有任何说明,但是如果你使用 Nixstaller,你可以得到 os.fileexists,这正好符合你所说的需求。

如果你能耐心地调试一下,或者你知道你将在哪个操作系统上运行,你可能可以通过标准os库的 os.execute 加上某些系统调用来识别文件是否存在。

比os.execute更好的选择可能是os.rename:

os.rename(oldname, newname)

将名为oldname的文件重命名为newname。 如果函数失败,则返回nil,加上描述错误的字符串。

你可以尝试将 oldname 和 newname 设置为相同的值——但是你可能没有写入权限,所以即使你可以读取,它也可能因为你无法写入而失败。在这种情况下,你需要解析返回的错误字符串并推断出是否可以写入,或者你需要尝试执行需要存在文件的函数,并用 pcall 包装它。

2009-08-27 10:58:53
stackoverflow用户68204
stackoverflow用户68204

问题在于 Lua 标准库几乎只包含标准 C 所指定的功能。标准 C 不会假设实际上存在某种特定类型的文件系统(甚至是操作系统),所以 osio 模块无法提供标准 C 库中不可用的访问信息。

如果您试图在纯标准 C 中编码,您会遇到相同的问题。

有一种方法可以通过尝试使用它来隐式地了解文件夹是否存在。如果您希望它存在并且您可以对其进行写操作,则创建一个临时文件并尝试写入。如果成功,则该文件夹存在,如果失败,则当然不能区分不存在的文件夹和权限不足。

最轻量级的获取特定答案的方法是绑定到只提供所需信息的那些特定于操作系统的函数调用。如果您接受 lua alien 模块,那么您可以在纯 Lua 中完成绑定。

更简单但略微重一些的方法是接受 Lua 文件系统。它提供了一个便携式模块,支持大多数关于文件和文件系统的信息获取。

2009-08-27 18:40:38
stackoverflow用户39182
stackoverflow用户39182

如果你特别想避免使用 LFS 库,可以使用 Lua Posix library 中的 stat() 接口。

require 'posix'
function isdir(fn)
    return (posix.stat(fn, "type") == 'directory')
end
2009-08-28 17:23:57
stackoverflow用户1709076
stackoverflow用户1709076

以下是一种简单的方法,可以检查文件夹是否存在而不需要任何外部库依赖 :)

function directory_exists(path)
  local f  = io.popen("cd " .. path)
  local ff = f:read("*all")

  if (ff:find("ItemNotFoundException")) then
    return false
  else
    return true
  end
end

print(directory_exists("C:\\Users"))
print(directory_exists("C:\\ThisFolder\\IsNotHere"))

如果你将上面的代码复制并粘贴到 Lua 中,你应该会看到

false
true

祝你好运 :)

2012-11-03 21:56:19
stackoverflow用户2904842
stackoverflow用户2904842

这段代码是在 Windows 平台上测试过的。实际上很容易:

function directory_exists( sPath )
  if type( sPath ) ~= "string" then return false end

  local response = os.execute( "cd " .. sPath )
  if response == 0 then
    return true
  end
  return false
end

显然,这可能在其他操作系统上无法正常工作。但对于 Windows 用户来说,这可能是一个解决方案 :)

2013-10-21 21:30:49
stackoverflow用户2764551
stackoverflow用户2764551

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

require("lfs")
-- 没有函数会检查错误。
-- 你应该检查它们

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
        -- 注意,简短的评估是为了
        -- 返回false而不是可能的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

-- 不使用 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

它看起来更短,但需要更长时间... 打开文件有风险,因此你应该使用 lfs。 如果你不关心性能(和错误处理 -.-),你可以直接使用它。

享受编程!

2014-02-07 21:00:48
stackoverflow用户1157217
stackoverflow用户1157217

对于 Linux 用户:

function dir_exists( path )
如果 type( path ) ~= 'string' then
    error('输入错误')
    return false
end
本地响应 = os.execute( 'cd ' .. path )
如果本地响应 == nil then
    返回 false
end
返回 本地响应
end
2016-02-25 02:28:04
stackoverflow用户2838606
stackoverflow用户2838606

你也可以使用 paths 包。这里是该包的链接。

然后在 Lua 中执行:

require 'paths'

if paths.dirp('your_desired_directory') then
    print 'it exists'
else
    print 'it does not exist'
end
2016-05-04 15:20:17
stackoverflow用户4984564
stackoverflow用户4984564

我在 Linux 上执行此操作的首选方式是:

if os.execute '[ -e "/home" ]' then
  io.write "it exists"
  if os.execute '[ -d "/home" ]' then
    io.write " and is a directory"
  end
  io.write "\n"
end

或者,将其放入函数中:

function is_dir(path)
  return os.execute(('[ -d "%s" ]'):format(path))
end -- 需要注意的是这种实现会返回一些其他值
2016-10-10 12:47:27
stackoverflow用户1793220
stackoverflow用户1793220

这是一种适用于Unix和Windows两个系统的方式,而且没有任何外部依赖:

--- 检查此路径下是否存在文件或目录
function exists(file)
   local ok, err, code = os.rename(file, file)
   if not ok then
      if code == 13 then
         -- 权限被拒绝,但是存在
         return true
      end
   end
   return ok, err
end

--- 检查此路径下是否存在目录
function isdir(path)
   -- “/”在Unix和Windows上都可以使用
   return exists(path.."/")
end
2016-10-22 18:04:41
stackoverflow用户3121768
stackoverflow用户3121768
本地函数 directory_exist(dir_path)
  本地 f = io.popen('[ -d "' .. dir_path .. '" ] && echo -n y')
  本地 result = f:read(1)
  f:close()
  返回 result == "y"
结束
2022-01-05 03:03:38
stackoverflow用户4896468
stackoverflow用户4896468

nixio.fs

一个广泛用于 OpenWrt 的包,

具有许多有用的功能,并且易于使用

文档:

http://openwrt.github.io/luci/api/modules/nixio.fs.html#nixio.fs.stat

fs.stat、lstat

> fs = require'nixio.fs'
> st = fs.stat('/tmp')
> = st.type=='dir'
true

> = fs.lstat'/var'.type=='lnk'
true

> = fs.stat'/bin/sh'.type=='reg'
true

测试:

> = pj(fs.stat'/var')
{
    "dev": 17,
    "type": "dir",
    "modedec": 755,
    "rdev": 0,
    "nlink": 28,
    "atime": 1617348683,
    "blocks": 0,
    "modestr": "rwxr-xr-x",
    "ino": 1136,
    "mtime": 1666474113,
    "gid": 0,
    "blksize": 4096,
    "ctime": 1666474113,
    "uid": 0,
    "size": 1960
}
> = pj(fs.lstat'/var')
{
    "dev": 19,
    "type": "lnk",
    "modedec": 777,
    "rdev": 0,
    "nlink": 1,
    "atime": 1613402557,
    "blocks": 0,
    "modestr": "rwxrwxrwx",
    "ino": 1003,
    "mtime": 1613402557,
    "gid": 0,
    "blksize": 1024,
    "ctime": 1613402557,
    "uid": 0,
    "size": 3
}

关于 stat()、lstat() 系统调用

Shell 测试运算符

[ -e 路径 ]

[ -f 路径 ]

[ -d 路径 ]

[ -L 路径 ]

低级别的两者都依赖于此系统调用。

$ strace test -e /var |& grep stat | tail -1
stat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

$ strace test -f /var |& grep stat | tail -1
stat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

$ strace test -d /var |& grep stat | tail -1
stat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

$ strace test -L /var |& grep stat | tail -1
lstat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
2022-10-22 21:43:39
stackoverflow用户18696276
stackoverflow用户18696276

这感觉如此简单,以至于我觉得没有其他人做这件事的原因。

但它可以运行在我的机器上(Ubuntu focal),对于文件和文件夹。

但是对于存在但是被禁止的文件会说它们不存在。

对于快速使用的脚本或少量文件:

function exists(path)
    return (io.open(path,"r") ~= nil)
end

良好的实践:

function exists(path)
    local file = io.open(path,"r")
    if (file ~= nil) then
        io.close(file)
        return true
    else
        return false
    end
end
2022-10-30 20:39:46