题 检查lua中是否存在目录?


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

试图做这样的python线:

os.path.isdir(path)

12
2017-08-27 10:37


起源




答案:


问题是,库存Lua分布(几乎)仅包括标准C中指定的功能。标准C没有假设实际存在任何特定类型的文件系统(甚至操作系统,就此而言) , 所以 os 和 io 模块不提供标准C库中没有的访问信息。

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

您可以通过尝试使用该文件夹来了解该文件夹是否存在。如果您希望它存在并且可以写入,那么在那里创建一个临时文件,如果成功,则该文件夹存在。如果失败,您当然可能无法将不存在的文件夹与权限不足区分开来。

到目前为止,获得特定答案的最轻量级答案将是对仅提供所需信息的特定于操作系统的函数调用的精简绑定。如果你能接受的话 lua外星人 模块,然后你可以喜欢在其他纯Lua中进行绑定。

更简单但更重一点的是接受Lua文件系统。它提供了一个便携式模块,支持大多数人可能想要了解的文件和文件系统。


12
2017-08-27 18:40





这种方法适用于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

10
2017-10-22 18:04



非常聪明的使用 os.rename 为了那个原因 - Lucas Siqueira


如果您对避免使用LFS库特别感兴趣,那么 Lua Posix图书馆 有一个stat()接口。

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

8
2017-08-28 17:23



但是,LuaPosix库要大得多,不能在Unix和Windows之间移植。 - Hisham H M


那么,5.1参考手册中没有任何内容 os表,但如果你使用 Nixstaller, 你得到 os.fileexists 正是你所解释的。

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

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

os.rename(oldname, newname)

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

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


5
2017-08-27 10:58





您也可以使用'paths'包。 这里这是包裹的链接

然后在Lua做:

require 'paths'

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

4
2018-05-04 15:20





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


2
2017-10-21 21:30



当我在linux和windows上测试时, response 是 nil 不管是否存在 sPath? - Alex
对于像这样简单的任务调用外部程序通常不被认为是好的做法,因为这往往会产生尽可能多的问题。在类Unix操作系统上 sPath 应引用参数(不确定Windows)并且这很难正确执行。 - Lassi


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

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

祝你好运 :)


1
2017-11-03 21:56



此解决方案似乎假设用户正在使用Powershell ...但是,检查cd命令的返回代码可能会有效。 - djs
我期待第一个结果为真,第二个结果为假。 - RAL


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

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。使用相同的名称,不应更改任何内容(除了有一个badass错误)。如果一切顺利,它返回true,否则返回nil和errormessage。你说你不想使用lfs。如果你不能在不试图打开文件的情况下区分文件和directorys(这有点慢但是没问题)。

所以没有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。 如果您不关心性能(和错误处理-.-),您可以使用它。

玩得开心!


1
2018-02-07 21:00



io.open 也适用于目录。你需要尝试阅读它(f:read(1)另外。 - blueyed
谢谢!不知道那个!如果文件为空(如果我添加'f:read(1)'),那也不会抛出错误吗?而AFAIK'f:read(0)'也无济于事...... - tDwtp


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

1
2017-10-10 12:47





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

0
2018-02-25 02:28