【问题标题】:Check if directory exists in lua?检查目录是否存在于lua中?
【发布时间】:2010-11-23 08:06:21
【问题描述】:

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

尝试做这样的 python 行:

os.path.isdir(path)

【问题讨论】:

    标签: lua io filesystems


    【解决方案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】:

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

    【讨论】:

      【解决方案3】:

      您也可以使用“路径”包。 Here是包的链接

      然后在 Lua 中执行:

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          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)' 也无济于事......
          【解决方案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上测试时,responsenil,不管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】:

          如果您对避免使用 LFS 库特别感兴趣,Lua Posix library 有一个到 stat() 的接口。

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

          【讨论】:

          • LuaPosix 库要大得多,但不能在 Unix 和 Windows 之间移植。
          【解决方案9】:

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

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

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

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

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

          【讨论】:

            【解决方案10】:

            嗯,5.1 参考手册在the os table 中没有任何内容,但如果您使用Nixstaller,您会得到os.fileexists,这正是您所解释的。

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

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

            os.rename(oldname, newname)

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

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-06-28
              • 2011-03-16
              • 1970-01-01
              • 1970-01-01
              • 2013-01-14
              相关资源
              最近更新 更多