Windows下Lua进行目录文件查找


目的:使用lua进行某个目录下特定类型或指定文件名的查找,并给出一个查找使用核心对象的函数实例。

require"lfs"

function findindir (path, wefind, r_table, intofolder)
    for file in lfs.dir(path) do
        if file ~= "." and file ~= ".." then
            local f = path..’\\’..file
            –print ("\t "..f)
            if string.find(f, wefind) ~= nil then
                –print("\t "..f)
                table.insert(r_table, f)
            end
            local attr = lfs.attributes (f)
            assert (type(attr) == "table")
            if attr.mode == "directory" and intofolder then
                findindir (f, wefind, r_table, intofolder)
            else
                –for name, value in pairs(attr) do
                –    print (name, value)
                –end
            end
        end
    end
end

要注意的是,这段代码使用了LuaFileSystem模块,最好使用Lua for windows这个统合安装包,里面已经包含了。

使用方法很简单,比如我想查找c盘下temp目录的所有cpp文件:

local currentFolder = [[C:\temp]]
————————————-
local input_table = {}
findindir(currentFolder, "%.cpp", input_table, true)

查找到的结果放在input_table中。另外可以使用第四个参数控制是否查找子目录。

给出一个实际的例子,想查找那些函数可能使用kernal object,通过它可以帮助查找是否可能存在handle泄露的情况。当我们找到文件,会在里面查找这些函数名,然后打印出行号。

参考文档是http://msdn.microsoft.com/en-us/library/ms724485%28VS.85%29.aspx

local currentFolder = [[C:\temp]]

local input_table = {}
findindir(currentFolder, "%.cpp", input_table, true)
findindir(currentFolder, "%.h", input_table, true)

    local tbl_found1 = {"CreateRestrictedToken",
                    "DuplicateToken",
                    "DuplicateTokenEx",
                    "OpenProcessToken",
                    "OpenThreadToken",
                    "FindFirstChangeNotification",
                    "CreateFile",
                    "GetThreadDesktop",
                    "OpenProcessToken",
                    "CreateEvent",
                    "CreateEventEx",
                    "OpenEvent",
                    "OpenEventLog",
                    "RegisterEventSource",
                    "OpenBackupEventLog",
                    "CreateFile",
                    "CreateFileMapping",
                    "OpenFileMapping",
                    "FindFirstFile",
                    "HeapCreate",
                    "CreateIoCompletionPort",
                    "CreateJobObject",
                    "CreateMailslot",
                    "CreateMemoryResourceNotification",
                    "LoadLibrary",
                    "GetModuleHandle",
                    "CreateMutex",
                    "CreateMutexEx",
                    "OpenMutex",
                    "CreateNamedPipe",
                    "CreatePipe",
                    "CreateProcess",
                    "OpenProcess",
                    "GetCurrentProcess",
                    "CreateSemaphore",
                    "CreateSemaphoreEx",
                    "OpenSemaphore",
                    "socket",
                    "accept",
                    "CreateThread",
                    "CreateRemoteThread",
                    "GetCurrentThread",
                    "CreateWaitableTimer",
                    "CreateWaitableTimerEx",
                    "OpenWaitableTimer",
                    "BeginUpdateResource",
                    "GetProcessWindowStation",}

        local tbl_found2 = {"CloseHandle",
                    "FindCloseChangeNotification",
                    "CloseEventLog",
                    "DeleteFile",
                    "FindClose",
                    "HeapDestroy",
                    "FreeLibrary",
                    "TerminateProcess",
                    "closesocket",
                    "EndUpdateResource",
                    "DeregisterEventSource",}

        local tbl_result1 = {}
        local tbl_result2 = {}

for _, foundname in ipairs(input_table) do
    local f = assert(io.open(foundname, "rb"))
    local linenum = 0
    while true do
        local buffer = f:read("*l")
        linenum = linenum + 1
        if not buffer then
            break
        end

        for ie = 1, table.maxn(tbl_found1) do
            local start1, end1 = string.find(buffer, tbl_found1[ie])
            local start2, end2 = string.find(buffer, "//")
            if start1 then
                if start2 and start2 < start1 then
                else
                    print("———————————-")
                    print(buffer, "\nline: " .. linenum, "\nfile: " .. foundname)
                    print("")
                    if tbl_result1[tbl_found1[ie]] == nil then
                        tbl_result1[tbl_found1[ie]] = 1
                    else
                        tbl_result1[tbl_found1[ie]] = tbl_result1[tbl_found1[ie]] + 1
                    end
                end
            end
        end

        for i2 = 1, table.maxn(tbl_found2) do
            local start1, end1 = string.find(buffer, tbl_found2[i2])
            local start2, end2 = string.find(buffer, "//")
            if start1 then
                if start2 and start2 < start1 then
                else
                    print("———————————-")
                    print(buffer, "\nline: " .. linenum, "\nfile: " .. foundname)
                    print("")

                    if tbl_result2[tbl_found2[i2]] == nil then
                        tbl_result2[tbl_found2[i2]] = 1
                    else
                        tbl_result2[tbl_found2[i2]] = tbl_result2[tbl_found2[i2]] + 1
                    end
                end
            end
        end
    end
end

print("result table1 ——————-")
print_table(tbl_result1)

print("")
print("result table2 ——————-")
print_table(tbl_result2)


《“Windows下Lua进行目录文件查找”》 有 1 条评论

  1. lua 的LFS模块有点问题,遇到乱码文件(explorer可识别)则直接报错退出了,难怪samples上需要加上一句 assert的!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注