Lua中如何检查目录是否存在?
如何在Lua中检查目录是否存在,最好不使用LuaFileSystem模块?
尝试像这样使用Python代码:
os.path.isdir(path)
原文链接 https://stackoverflow.com/questions/1340230
问题在于 Lua 标准库几乎只包含标准 C 所指定的功能。标准 C 不会假设实际上存在某种特定类型的文件系统(甚至是操作系统),所以 os
和 io
模块无法提供标准 C 库中不可用的访问信息。
如果您试图在纯标准 C 中编码,您会遇到相同的问题。
有一种方法可以通过尝试使用它来隐式地了解文件夹是否存在。如果您希望它存在并且您可以对其进行写操作,则创建一个临时文件并尝试写入。如果成功,则该文件夹存在,如果失败,则当然不能区分不存在的文件夹和权限不足。
最轻量级的获取特定答案的方法是绑定到只提供所需信息的那些特定于操作系统的函数调用。如果您接受 lua alien 模块,那么您可以在纯 Lua 中完成绑定。
更简单但略微重一些的方法是接受 Lua 文件系统。它提供了一个便携式模块,支持大多数关于文件和文件系统的信息获取。
如果你特别想避免使用 LFS 库,可以使用 Lua Posix library 中的 stat() 接口。
require 'posix'
function isdir(fn)
return (posix.stat(fn, "type") == 'directory')
end
以下是一种简单的方法,可以检查文件夹是否存在而不需要任何外部库依赖 :)
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
祝你好运 :)
这段代码是在 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 用户来说,这可能是一个解决方案 :)
我使用以下代码(但实际上检查错误):
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。 如果你不关心性能(和错误处理 -.-),你可以直接使用它。
享受编程!
对于 Linux 用户:
function dir_exists( path )
如果 type( path ) ~= 'string' then
error('输入错误')
return false
end
本地响应 = os.execute( 'cd ' .. path )
如果本地响应 == nil then
返回 false
end
返回 本地响应
end
你也可以使用 paths
包。这里是该包的链接。
然后在 Lua 中执行:
require 'paths'
if paths.dirp('your_desired_directory') then
print 'it exists'
else
print 'it does not exist'
end
我在 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 -- 需要注意的是这种实现会返回一些其他值
这是一种适用于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
本地函数 directory_exist(dir_path)
本地 f = io.popen('[ -d "' .. dir_path .. '" ] && echo -n y')
本地 result = f:read(1)
f:close()
返回 result == "y"
结束
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
这感觉如此简单,以至于我觉得没有其他人做这件事的原因。
但它可以运行在我的机器上(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
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
好的,5.1参考手册在 os表 没有任何说明,但是如果你使用 Nixstaller,你可以得到
os.fileexists
,这正好符合你所说的需求。如果你能耐心地调试一下,或者你知道你将在哪个操作系统上运行,你可能可以通过标准os库的
os.execute
加上某些系统调用来识别文件是否存在。比os.execute更好的选择可能是os.rename:
你可以尝试将 oldname 和 newname 设置为相同的值——但是你可能没有写入权限,所以即使你可以读取,它也可能因为你无法写入而失败。在这种情况下,你需要解析返回的错误字符串并推断出是否可以写入,或者你需要尝试执行需要存在文件的函数,并用
pcall
包装它。