检查lua中是否存在目录?

发布于 2024-08-02 21:29:45 字数 128 浏览 3 评论 0原文

如何检查 lua 中是否存在目录,如果可能的话最好不使用 LuaFileSystem 模块?

尝试做类似以下 python 行的事情:

os.path.isdir(path)

How do I check if a directory exists in lua, preferably without using the LuaFileSystem module if possible?

Trying to do something like this python line:

os.path.isdir(path)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

送舟行 2024-08-09 21:29:45

这是一种在 Unix 和 Windows 上都适用的方式,无需任何外部依赖:

--- Check if a file or directory exists in this path
function exists(file)
   local ok, err, code = os.rename(file, file)
   if not ok then
      if code == 13 then
         -- Permission denied, but it exists
         return true
      end
   end
   return ok, err
end

--- Check if a directory exists in this path
function isdir(path)
   -- "/" works on both Unix and Windows
   return exists(path.."/")
end

This is a way that works on both Unix and Windows, without any external dependencies:

--- Check if a file or directory exists in this path
function exists(file)
   local ok, err, code = os.rename(file, file)
   if not ok then
      if code == 13 then
         -- Permission denied, but it exists
         return true
      end
   end
   return ok, err
end

--- Check if a directory exists in this path
function isdir(path)
   -- "/" works on both Unix and Windows
   return exists(path.."/")
end
¢好甜 2024-08-09 21:29:45

问题在于,现有的 Lua 发行版(几乎)只包含标准 C 中指定的功能。标准 C 没有假设实际上存在任何特定类型的文件系统(甚至是操作系统) ,因此 osio 模块不提供标准 C 库中不可用的访问信息。

如果您尝试使用纯标准 C 进行编码,您也会遇到同样的问题。

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

到目前为止,获得特定答案的最轻量级答案是对那些提供所需信息的特定于操作系统的函数调用的精简绑定。如果你可以接受 lua Alien 模块,那么你就可以在其他纯 Lua 中进行绑定。

更简单但稍微重一点的是接受 Lua 文件系统。它提供了一个可移植的模块,支持人们可能想要了解的有关文件和文件系统的大多数内容。

The problem is that the stock Lua distribution (nearly) only includes features that are specified in standard C. Standard C makes no presumptions about there actually being a file system of any specific sort out there (or even an operating system, for that matter), so the os and io modules don't provide access information not available from the standard C library.

If you were attempting to code in pure standard C, you would have the same issue.

There is a chance that you can learn whether the folder exists implicitly from an attempt to use it. If you expect it to exist and be writable to you, then create a temporary file there and if the that succeeds, the folder exists. If it fails, you might not be able to distinguish a non-existent folder from insufficient permissions, of course.

By far the lightest-weight answer to getting a specific answer would be a thin binding to just those OS-specific function calls that provide the information you need. If you can accept the lua alien module, then you can like do the binding in otherwise pure Lua.

Simpler, but slightly heavier, is to accept Lua File System. It provides a portable module that supports most things one might want to learn about files and the file system.

梦太阳 2024-08-09 21:29:45

如果您特别有兴趣避免使用 LFS 库,Lua Posix 库 有一个接口统计()。

require 'posix'
function isdir(fn)
    return (posix.stat(fn, "type") == 'directory')
end

If you're specifically interested in avoiding the LFS library, the Lua Posix library has an interface to stat().

require 'posix'
function isdir(fn)
    return (posix.stat(fn, "type") == 'directory')
end
小猫一只 2024-08-09 21:29:45

好吧,5.1 参考手册在 os 表 中没有任何内容,但是如果您使用 < a href="http://nixstaller.berlios.de/news.php" rel="noreferrer">Nixstaller,你会得到os.fileexists 正是您所解释的内容。

如果您有能力摆弄一下,或者如果您知道将在什么操作系统上运行,您可能会使用标准操作系统库的 os.execute 以及一些系统调用来识别是否该文件存在。

甚至比 os.execute 更好的可能是 os.rename:

os.rename(旧名称,新名称)

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

您可以尝试将 oldname 和 newname 设置为相同 - 但您可能没有写入权限,因此它可能会失败,因为您无法写入,即使您可以读取。在这种情况下,您必须解析返回的错误字符串并推断您是否可以编写,或者您必须尝试执行需要现有文件的函数,并将其包装在 pcall

Well, the 5.1 reference manual doesn't have anything in the os table, but if you use Nixstaller, you get os.fileexists for precisely what you've explained.

If you can afford to fiddle around a bit, or if you know what OS you'll be running on, you might get away with the standard os library's os.execute with some system call that will identify if the file exists.

Even better than os.execute might be os.rename:

os.rename(oldname, newname)

Renames file named oldname to newname.
If this function fails, it returns
nil, plus a string describing the
error.

You could try setting oldname and newname the same -- you might not have write permissions, though, so it might fail because you can't write, even though you can read. In that event, you'd have to parse the returned error string and deduce whether you could write, or you'd have to just try executing your function that needs an existing file, and wrap it in a pcall.

叫思念不要吵 2024-08-09 21:29:45

您还可以使用“paths”包。 这里是包的链接

然后在 Lua 中执行以下操作:

require 'paths'

if paths.dirp('your_desired_directory') then
    print 'it exists'
else
    print 'it does not exist'
end

You can also use the 'paths' package. Here's the link to the package

Then in Lua do:

require 'paths'

if paths.dirp('your_desired_directory') then
    print 'it exists'
else
    print 'it does not exist'
end
尘世孤行 2024-08-09 21:29:45

这是针对windows平台进行测试的。实际上这很简单:

local 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 用户来说,这可能是一个解决方案:)

This is tested for the windows platform. It is quite easy actually:

local 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

Obviously, this may not work on other OS's. But for windows users, this can be a solution :)

我使用这些(但实际上我检查了错误):

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

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

祝你编码愉快!

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. You said you dont want to use lfs. If you dont you cant differentiate between files and directorys 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, because of that you should use lfs.
If you don't care about performance (and errorhandling -.-) you can just use it.

Have fun coding!

生寂 2024-08-09 21:29:45

这里有一个简单的方法来检查文件夹是否存在而没有任何外部库依赖:)

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

好运:)

here is a simple way to check if a folder exists WITHOUT ANY EXTERNAL LIBRARY DEPENDENCIES :)

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

If you copy and paste the above into Lua you should see

false
true

good luck :)

清醇 2024-08-09 21:29:45

这感觉太简单了,我觉得这是有原因的,没有人这样做过。

但它可以在我的机器(Ubuntu focus)上运行,用于文件和目录。

但它确实表示存在但禁止的文件不存在。

对于快速脚本和/或少量文件:

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

This feels so simple that I feel like there's a reason nobody else has done this.

But it works on my machine (Ubuntu focal), for files and directories.

It does however say that existent-yet-forbidden files don't exist.

For quick scripts and/or few files:

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

Good practice:

function exists(path)
    local file = io.open(path,"r")
    if (file ~= nil) then
        io.close(file)
        return true
    else
        return false
    end
end
久隐师 2024-08-09 21:29:45

对于 Linux 用户:

function dir_exists( path )
if type( path ) ~= 'string' then
    error('input error')
    return false
end
local response = os.execute( 'cd ' .. path )
if response == nil then
    return false
end
return response
end

For Linux users:

function dir_exists( path )
if type( path ) ~= 'string' then
    error('input error')
    return false
end
local response = os.execute( 'cd ' .. path )
if response == nil then
    return false
end
return response
end
总攻大人 2024-08-09 21:29:45

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

or,将其放入函数中:

function is_dir(path)
  return os.execute(('[ -d "%s" ]'):format(path))
end -- note that this implementation will return some more values

My preferred way of doing this in linux is

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

or, to put this into a function:

function is_dir(path)
  return os.execute(('[ -d "%s" ]'):format(path))
end -- note that this implementation will return some more values
瞳孔里扚悲伤 2024-08-09 21:29:45

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

低级别都依赖于这个系统调用。

$ 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

nixio.fs

a package widely used in openwrt,
has lots of useful functions, and easy to use

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

tests:

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

about stat(), lstat() syscall

shell test operator
[ -e path ]
[ -f path ]
[ -d path ]
[ -L path ]

low level both rely on this syscall.

$ 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
不气馁 2024-08-09 21:29:45

您尝试避免使用 LuaFileSystem,但为了完整性/比较,这里有一个使用它的答案:

local lfs = require "lfs"

function isdir(path)
  return lfs.attributes(path, "mode") == "directory"
end

You to try to avoid LuaFileSystem, but for completeness/comparison here's an answer using it:

local lfs = require "lfs"

function isdir(path)
  return lfs.attributes(path, "mode") == "directory"
end
飘落散花 2024-08-09 21:29:45
local function directory_exist(dir_path)
  local f = io.popen('[ -d "' .. dir_path .. '" ] && echo -n y')
  local result = f:read(1)
  f:close()
  return result == "y"
end

试试这个

local function directory_exist(dir_path)
  local f = io.popen('[ -d "' .. dir_path .. '" ] && echo -n y')
  local result = f:read(1)
  f:close()
  return result == "y"
end

try this

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文