from http://sunxiunan.com/?p=1285
目的:使用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(VS.85).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)