我需要LUA中的目录列表
假设我有一个目录路径为“C:\ Program Files”
我需要该特定路径中所有文件夹的列表以及如何搜索该列表中的任何特定文件夹。
例
需要路径“C:\ Program Files”中所有文件夹的列表
以下是上述路径中的文件夹名称
试过下面的代码。我在下面遗漏的东西: -
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\\")
采取简单的方法,安装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 /中也是允许的(如果我在这个问题上错了,请纠正我)。
我讨厌必须安装库(特别是那些希望我使用安装程序包来安装它们的库)。如果您正在为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'
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
...
每次循环时,您都会获得一个新的文件夹名称。我选择以打印为例。
我不喜欢安装库,我正在使用内存功耗更低的嵌入式设备。我发现使用'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
IIRC,使用Lua库存无法获取目录列表。您需要自己编写一些胶水代码,或使用LuaFileSystem。后者很可能是你阻力最小的道路。快速扫描文档显示lfs.dir()
,它将为您提供一个迭代器,您可以使用它来获取您正在寻找的目录。此时,您可以进行字符串比较以获取所需的特定目录。
您还可以安装和使用'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
第二个代码也排除了诸如'。'之类的文件。和'..'。所以去吧真好!
不要解析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
警告:但是,作为加入的答案,如果目录名称中包含'
,则可以利用此apporach。只有一个安全的解决方案是使用lfs
或其他特殊库。