如何获取Lua中的目录列表

时间:2011-03-14 19:05:23

标签: lua filenames directory-listing

我需要LUA中的目录列表

假设我的目录路径为“C:\ Program Files”

我需要该特定路径中所有文件夹的列表以及如何搜索该列表中的任何特定文件夹。

实施例

需要路径“C:\ Program Files”

中所有文件夹的列表

以下是上述路径中的文件夹名称

  1. test123
  2. test4567
  3. folder 123
  4. 文件夹456
  5. 文件夹456 789

    需要在列表中获取上述内容,然后必须仅搜索文件夹456 789中的文件夹456等特定字符串。

  6. 尝试下面的代码。我在下面遗漏的东西: -

    local function Loc_Lines( str )
    --
    local ret= {}   -- 0 lines
    
    while str do
        local _,_,line,tail= string.find( str, "(.-)\n(.+)" )
        table.insert( ret, line or str )
        str= tail
      Print (str)
    end
    
    return ret
    end
    
    
    local function Loc_ShellCommand( cmd )
    --
    local str= nil
    
        --
        local f= io.popen( cmd )    -- no command still returns a handle :(
         if f then
    
            str= f:read'*a'
        Print(str)
            f:close()
        end
    
        if str=="" then   -- take no output as a failure (we can't tell..)
        Print("hi")
            str= nil
        end
    
    -- Remove terminating linefeed, if any (eases up one-line analysis)
    --
    if str then
        if string.sub( str, -1 ) == '\n' then
            str= string.sub( str, 1, -2 )
        end
    end
    
    return str
     end
    
    
     local function Loc_DirCmd( cmd )
    
     Print(cmd)
    
      local str= Loc_ShellCommand( cmd )
    
    
    
     return Loc_Lines(str)
     end
    
    
    local function Loc_DirList( dirname )
    
     local ret= {}
    
        local lookup= {}
    
       local tbl= Loc_DirCmd( "dir /AD /B "..dirname )   -- only dirs
    
        -- Add slash to every dir line
        --
        for i,v in ipairs(tbl) do
            table.insert( ret, v..'\\' )
            lookup[v]= true
        end       
    
    
        -- Return with forward slashes
        --
        if true then
            for i=1,table.getn(ret) do
                ret[i]= string.gsub( ret[i], '\\', '/' )
         Print (ret[i])
            end
        end
    
    
       return ret
     end
    
    
     Loc_DirList("C:\\Program Files\\")
    

8 个答案:

答案 0 :(得分:46)

我讨厌必须安装库(特别是那些希望我使用安装程序包来安装它们的库)。如果您正在为Lua中的绝对路径上的目录列表寻找一个干净的解决方案,请不要再看了。

在sylvanaar提供的答案的基础上,我创建了一个函数,该函数返回给定目录的所有文件的数组(需要绝对路径)。这是我首选的实现,因为它可以在我的所有机器上运行。

-- Lua implementation of PHP scandir function
function scandir(directory)
    local i, t, popen = 0, {}, io.popen
    local pfile = popen('ls -a "'..directory..'"')
    for filename in pfile:lines() do
        i = i + 1
        t[i] = filename
    end
    pfile:close()
    return t
end

如果您使用的是Windows,则需要安装bash客户端,以便'ls'命令可以正常工作 - 或者,您可以使用sylvanaar提供的dir命令:

'dir "'..directory..'" /b /ad'

答案 1 :(得分:25)

采取简单的方法,安装lfs。然后使用以下构造来查找所需内容:

require'lfs'
for file in lfs.dir[[C:\Program Files]] do
    if lfs.attributes(file,"mode") == "file" then print("found file, "..file)
    elseif lfs.attributes(file,"mode")== "directory" then print("found dir, "..file," containing:")
        for l in lfs.dir("C:\\Program Files\\"..file) do
             print("",l)
        end
    end
end

注意反斜杠等于[[\]]等于"\\",如果没有在cmd本身上使用,那么在windows /中也是允许的(如果我在这个问题上错了,请纠正我)。

答案 2 :(得分:16)

 for dir in io.popen([[dir "C:\Program Files\" /b /ad]]):lines() do print(dir) end

*适用于Windows

输出:

Adobe
Bitcasa
Bonjour
Business Objects
Common Files
DVD Maker
IIS
Internet Explorer
iPod
iTunes
Java
Microsoft Device Emulator
Microsoft Help Viewer
Microsoft IntelliPoint
Microsoft IntelliType Pro
Microsoft Office
Microsoft SDKs
Microsoft Security Client
Microsoft SQL Server
Microsoft SQL Server Compact Edition
Microsoft Sync Framework
Microsoft Synchronization Services
Microsoft Visual Studio 10.0
Microsoft Visual Studio 9.0
Microsoft.NET
MSBuild
...

每次循环都会给你一个新的文件夹名称。我选择打印它作为一个例子。

答案 3 :(得分:13)

我不喜欢安装库,而且我正在使用内存功耗更低的嵌入式设备。我发现使用'ls'命令会导致内存不足。所以我创建了一个使用'find'来解决问题的函数。

这样可以保持内存使用稳定并循环所有30k文件。

function dirLookup(dir)
   local p = io.popen('find "'..dir..'" -type f')  --Open directory look for files, save data in p. By giving '-type f' as parameter, it returns all files.     
   for file in p:lines() do                         --Loop through all files
       print(file)       
   end
end

答案 4 :(得分:2)

IIRC,使用库存Lua无法获取目录列表。您需要自己编写一些胶水代码,或使用LuaFileSystem。后者很可能是你阻力最小的道路。快速扫描文档显示lfs.dir(),它将为您提供一个迭代器,您可以使用它来获取您要查找的目录。此时,您可以进行字符串比较以获取所需的特定目录。

答案 5 :(得分:1)

您还可以安装和使用' paths'模块。然后您可以轻松地执行以下操作:

require 'paths'

currentPath = paths.cwd() -- Current working directory
folderNames = {}
for folderName in paths.files(currentPath) do
    if folderName:find('$') then
        table.insert(folderNames, paths.concat(currentPath, folderName))
    end
end

print (folderNames)

- 这将打印所有文件夹名称

或者,您也可以将fileName:find('$')替换为fileName:find('txt' .. '$')

,以查找具有特定扩展名的文件名

如果您在基于Unix的计算机上运行,​​则可以使用以下代码获取数字排序文件列表:

thePath = '/home/Your_Directory'
local handle = assert(io.popen('ls -1v ' .. thePath)) 
local allFileNames = string.split(assert(handle:read('*a')), '\n')

print (allFileNames[1]) -- This will print the first file name

第二个代码也会排除'等文件。'和' ..'。这样很好!

答案 6 :(得分:0)

不要解析ls,这是邪恶的!改为使用find和零结尾的字符串(在Linux上):

function scandir(directory)
    local i, t = 0, {}
    local pfile = assert(io.popen(("find '%s' -maxdepth 1 -print0"):format(directory), 'r'))
    local list = pfile:read('*a')
    pfile:close()
    for filename in s:gmatch('[^\0]+')
        i = i + 1
        t[i] = filename
    end
    return t
end

警告:但是,如果目录名称中包含',则可以采用此方法作为正确的答案。只有一种安全的解决方案是使用lfs或其他特殊库。

答案 7 :(得分:0)

val says Reinstate Monica解决方案的一些修补程序:

function scandir(directory)
    local pfile = assert(io.popen(("find '%s' -mindepth 1 -maxdepth 1 -type d -printf '%%f\\0'"):format(directory), 'r'))
    local list = pfile:read('*a')
    pfile:close()

    local folders = {}

    for filename in string.gmatch(list, '[^%z]+') do
        table.insert(folders, filename)
    end

    return folders
end

现在,它按文件夹过滤,不包含目录本身,仅显示名称。