检查目录是不是存在于lua中?
Posted
技术标签:
【中文标题】检查目录是不是存在于lua中?【英文标题】:Check if directory exists in lua?检查目录是否存在于lua中? 【发布时间】:2010-11-23 08:06:21 【问题描述】:如何检查 lua 中是否存在目录,如果可能,最好不使用 LuaFileSystem 模块?
尝试做这样的 python 行:
os.path.isdir(path)
【问题讨论】:
【参考方案1】:这是一种适用于 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
【讨论】:
非常聪明地使用了os.rename
【参考方案2】:
问题在于,现有的 Lua 发行版(几乎)仅包含标准 C 中指定的功能。标准 C 没有假设实际上存在任何特定类型的文件系统(甚至是操作系统,例如那件事),所以os
和io
模块不提供标准C 库中没有的访问信息。
如果您尝试使用纯标准 C 进行编码,您也会遇到同样的问题。
您有机会通过尝试使用该文件夹来了解该文件夹是否隐式存在。如果您希望它存在并且对您可写,则在此处创建一个临时文件,如果成功,则该文件夹存在。当然,如果失败,您可能无法将不存在的文件夹与权限不足区分开来。
到目前为止,获得特定答案的最轻量级的答案是对那些提供您需要的信息的特定于操作系统的函数调用进行精简绑定。如果您可以接受lua alien 模块,那么您可以喜欢在其他纯Lua 中进行绑定。
更简单,但稍重一些,就是接受 Lua 文件系统。它提供了一个可移植的模块,支持人们可能想了解的有关文件和文件系统的大部分内容。
【讨论】:
【参考方案3】:如果您对避免使用 LFS 库特别感兴趣,Lua Posix library 有一个到 stat() 的接口。
require 'posix'
function isdir(fn)
return (posix.stat(fn, "type") == 'directory')
end
【讨论】:
LuaPosix 库要大得多,但不能在 Unix 和 Windows 之间移植。【参考方案4】:嗯,5.1 参考手册在the os table 中没有任何内容,但如果您使用Nixstaller,您会得到os.fileexists
,这正是您所解释的。
如果您有能力摆弄一下,或者如果您知道您将在哪个操作系统上运行,您可能会使用标准操作系统库的os.execute
并通过一些系统调用来识别文件是否存在。
甚至比 os.execute 更好的可能是 os.rename:
os.rename(oldname, newname)
将名为
oldname
的文件重命名为newname
。 如果此函数失败,则返回 nil,加上一个描述 错误。
您可以尝试将 oldname 和 newname 设置为相同 - 但是您可能没有写入权限,因此它可能会因为您无法写入而失败,即使您可以读取。在这种情况下,您必须解析返回的错误字符串并推断您是否可以编写,或者您必须尝试执行需要现有文件的函数,并将其包装在 pcall
中。
【讨论】:
【参考方案5】:您也可以使用“路径”包。 Here是包的链接
然后在 Lua 中执行:
require 'paths'
if paths.dirp('your_desired_directory') then
print 'it exists'
else
print 'it does not exist'
end
【讨论】:
【参考方案6】:这是针对 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用户来说,这可能是一个解决方案:)
【讨论】:
当我在linux和windows上测试时,response
是nil
,不管sPath
是否存在?
为这样简单的任务调用外部程序通常不被认为是好的做法,因为这往往会产生与解决问题一样多的问题。在类 Unix 操作系统上,sPath
参数应该被引用(不确定 Windows),这很难做到正确。【参考方案7】:
这是一个简单的方法来检查一个文件夹是否存在而没有任何外部库依赖:)
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
祝你好运:)
【讨论】:
这个解决方案似乎假设用户正在使用 Powershell...不过,检查 cd 命令的返回码可能会奏效。 我期待第一个结果为真,第二个结果为假。 @RAL 只需输入not directory_exists("C:\\ThisFolder\\IsNotHere")
【参考方案8】:
我使用这些(但我实际上检查了错误):
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。 如果您不关心性能(和错误处理-.-),您可以使用它。
玩得开心!
【讨论】:
io.open
也适用于目录。您还需要尝试阅读它 (f:read(1)
)。
谢谢!不知道!如果文件为空(如果我添加'f:read(1)'),那是否也会引发错误?而且 AFAIK 'f:read(0)' 也无济于事......【参考方案9】:
我在 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 -- note that this implementation will return some more values
【讨论】:
【参考方案10】:对于 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
【讨论】:
【参考方案11】: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
试试这个
【讨论】:
以上是关于检查目录是不是存在于lua中?的主要内容,如果未能解决你的问题,请参考以下文章
Perl LWP::Simple::getstore 如何检查文件是不是存在于目标目录中