找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 5833|回复: 11

[教程源码] LUA插件-遍历文件夹、对比文件变化、检测是否有新文件生成

[复制链接]
  • 打卡等级:无名新人

2

主题

7

回帖

11

积分

按键电脑&手机班学员

鲜花
0
猫粮
73
发表于 2019-4-21 21:21:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
调用方式:
[按键精灵] 纯文本查看 复制代码
dim ret1=my_lua.SaveFileList("/data/test")
TracePrint (zm.varInfo(ret1))

Delay 30000	//这时间去删除复制文件了

dim ret2=my_lua.SaveFileList("/data/test","test.txt")
TracePrint (zm.varInfo(ret2))
TracePrint ret2["filepath"]

Dim ret3=my_lua.CompareFileList(ret1,ret2["filepath"])
TracePrint (zm.VarInfo(ret3))
TracePrint ("文件差异====》被删除的文件:"&zm.varInfo(ret3["filedelete"])&",新生成文件:"&zm.varInfo(ret3["filecreate"]))


结果类似:

zm1.png



源码:
[按键精灵] 纯文本查看 复制代码
--[=[
@fname:FileWrite
@cname:把table的key保存为文本文件,和一般保存表的valua不一样
@arg:filepath为要保存的文本路径,
@arg:texttable格式是table,要保存的表
@ret:成功返回一个1,失败返回nil
--]=]
function FileWrite(filepath, texttable)
    if (not filepath) or (not texttable) then
        LuaAuxLib.TracePrint("参数错误")
        return nil
    end
    local f = io.open(filepath, "w")
    if f == nil then
        LuaAuxLib.TracePrint(filepath .. "打开失败")
        return nil
    end
    for k, v in pairs(texttable) do
        f:write(k .. "\n")
    end
    f:close()
    return 1
end

--[=[
@fname:FileReadLines
@cname:读文本
@arg:filepath要操作的文件路径
@ret:成功返回一个table,参考下面.失败返回nil
--]=]
function FileReadLines(filepath)
    if not filepath then
        LuaAuxLib.TracePrint("参数错误")
        return nil
    end
    local f = io.open(filepath, "r")
    if f == nil then
        return nil
    end
    local texttable = {}
    for str in f:lines() do
        --LuaAuxLib.TracePrint(str)
        texttable[str] = true
    end
    f:close()
    return texttable
end
QMPlugin.FileReadLines = FileReadLines

--[=[
@fname:SaveFileList
@cname:遍历文件夹,包括所有子文件
@arg:dirPath,要遍历的文件夹目录
@arg:savaPath,可选参数,文件名包括路径以每行一个的方式保存在此文本.可以是绝对、相对路径,或只写文件名.如不填则不保存
@ret:失败返回-1
@ret:成功时:
@ret:1、如果有savaPath参数说明需要保存以备后用,返回一个table,格式为{ ["filepath"] = cachePath, ["filetable"]=filetable },cachePath是生成的文本路径,filetable以key来记录所有文件,类似:{"filepath":"/storage/emulated/0/MobileAnjian/test.txt","filetable":{"/data/test/ajjl.db":true,"/data/test/b.txt":true,"/data/test/zmplugin/lockbox/cipher/aes128.lua":true}}
@ret:2、如果没有savaPath参数则直接返回filetable,大概这样:{"/data/test/ajjl.db":true,"/data/test/b.txt":true,"/data/test/zmplugin/lockbox/cipher/aes128.lua":true}
@example:按键精灵调用:
@example:dim ret1=my_lua.SaveFileList("/data/test","test.txt")
@example:TracePrint (zm.varInfo(ret1))
@example:TracePrint "保存路径为:" & ret1["filepath"]
@example:结果大概这样:
@example:{"filepath":"/storage/emulated/0/MobileAnjian/test.txt","filetable":{"/data/test/ajjl.db":true,"/data/test/b.txt":true,"/data/test/zmplugin/lockbox/cipher/aes128.lua":true}}
@example:保存路径为:/storage/emulated/0/MobileAnjian/test.txt
--]=]
function SaveFileList(dirPath, savaPath)

    if not dirPath then
        LuaAuxLib.TracePrint("参数错误")
        return -1
    end

    local filetable = {}
    local rootPath = dirPath
    local cachePath
    if savaPath then
        if savaPath:find("/") then
            cachePath = savaPath
        else
            cachePath = __MQM_RUNNER_LOCAL_PATH_GLOBAL_NAME__ .. savaPath
        end
    end
    local function GetAllFiles(rootPath)
        --LuaAuxLib.TracePrint("遍历中")
        local f
        for f in lfs.dir(rootPath) do
            if f ~= '.' and f ~= '..' then
                local path = rootPath .. "/" .. f
                local attr = lfs.attributes(path)
                if type(attr) ~= "table" then
                    LuaAuxLib.TracePrint(path .. "属性获取失败")
                    return -1
                end
                if (attr.mode == "directory") then
                    GetAllFiles(path) --自调用遍历子目录
                elseif attr.mode == "file" then
                    filetable[path] = true
                end
            end
        end
    end

    if GetAllFiles(rootPath) == -1 then
        LuaAuxLib.TracePrint(cachePath .. "目录下的文件列表保存失败")
        return -1
    end
    if not savaPath then
        return filetable or -1
    end
    pcall(function()
        if FileWrite(cachePath, filetable) then
            return 1
        else
            cachePath = string.gsub(cachePath, "^/storage/emulated/0/", "/sdcard/", 1)
            if FileWrite(cachePath, filetable) then
                return 1
            else
                return -1
            end
        end
    end)
    if filetable then
        return { ["filepath"] = cachePath, ["filetable"] = filetable }
    else
        return -1
    end
end
QMPlugin.SaveFileList = SaveFileList

--[=[
@fname:CompareFileList
@cname:比较2个文本文件的内容,记录文件差异,用来检查是否添加新文件
@arg:文件路径1,文件路径2, string, 要操作的文件路径
@ret:成功返回一个table,里面有2个table,第一个为firstpath有而secondpath没有的,第二个为secondpath有而firstpath没有的
--]=]
function CompareFileList(firstpath, secondpath)
    if (not firstpath) or (not secondpath) then
        return nil
    end
    local ret1 = {}
    local ret2 = {}
    local strtable1 = {}
    local strtable2 = {}

    if type(firstpath) == "string" then
        strtable1 = FileReadLines(firstpath)
    elseif type(firstpath) == "table" then
        strtable1 = firstpath
    else
        return nil
    end

    if type(secondpath) == "string" then
        strtable2 = FileReadLines(secondpath)
    elseif type(secondpath) == "table" then
        strtable2 = secondpath
    else
        return nil
    end
    for k, _ in pairs(strtable2) do
        if not strtable1[k] then
            --LuaAuxLib.TracePrint(k)
            ret2[k] = true
            --LuaAuxLib.TracePrint(zm.VarInfo(ret1))
        else
            strtable1[k] = nil
        end
    end
    ret1 = strtable1

    return { ["filedelete"]=ret1,["filecreate"]=ret2 }
end
QMPlugin.CompareFileList = CompareFileList


楼主热帖
学号3338
  • 打卡等级:无名新人

2

主题

7

回帖

11

积分

按键电脑&手机班学员

鲜花
0
猫粮
73
 楼主| 发表于 2019-4-21 21:22:23 | 显示全部楼层
源码发下按键格式了,还找不到地方编辑。

[Lua] 纯文本查看 复制代码
--[=[
@fname:FileWrite
@cname:把table的key保存为文本文件,和一般保存表的valua不一样
@arg:filepath为要保存的文本路径,
@arg:texttable格式是table,要保存的表
@ret:成功返回一个1,失败返回nil
--]=]
function FileWrite(filepath, texttable)
    if (not filepath) or (not texttable) then
        LuaAuxLib.TracePrint("参数错误")
        return nil
    end
    local f = io.open(filepath, "w")
    if f == nil then
        LuaAuxLib.TracePrint(filepath .. "打开失败")
        return nil
    end
    for k, v in pairs(texttable) do
        f:write(k .. "\n")
    end
    f:close()
    return 1
end
 
--[=[
@fname:FileReadLines
@cname:读文本
@arg:filepath要操作的文件路径
@ret:成功返回一个table,参考下面.失败返回nil
--]=]
function FileReadLines(filepath)
    if not filepath then
        LuaAuxLib.TracePrint("参数错误")
        return nil
    end
    local f = io.open(filepath, "r")
    if f == nil then
        return nil
    end
    local texttable = {}
    for str in f:lines() do
        --LuaAuxLib.TracePrint(str)
        texttable[str] = true
    end
    f:close()
    return texttable
end
QMPlugin.FileReadLines = FileReadLines
 
--[=[
@fname:SaveFileList
@cname:遍历文件夹,包括所有子文件
@arg:dirPath,要遍历的文件夹目录
@arg:savaPath,可选参数,文件名包括路径以每行一个的方式保存在此文本.可以是绝对、相对路径,或只写文件名.如不填则不保存
@ret:失败返回-1
@ret:成功时:
@ret:1、如果有savaPath参数说明需要保存以备后用,返回一个table,格式为{ ["filepath"] = cachePath, ["filetable"]=filetable },cachePath是生成的文本路径,filetable以key来记录所有文件,类似:{"filepath":"/storage/emulated/0/MobileAnjian/test.txt","filetable":{"/data/test/ajjl.db":true,"/data/test/b.txt":true,"/data/test/zmplugin/lockbox/cipher/aes128.lua":true}}
@ret:2、如果没有savaPath参数则直接返回filetable,大概这样:{"/data/test/ajjl.db":true,"/data/test/b.txt":true,"/data/test/zmplugin/lockbox/cipher/aes128.lua":true}
@example:按键精灵调用:
@example:dim ret1=my_lua.SaveFileList("/data/test","test.txt")
@example:TracePrint (zm.varInfo(ret1))
@example:TracePrint "保存路径为:" & ret1["filepath"]
@example:结果大概这样:
@example:{"filepath":"/storage/emulated/0/MobileAnjian/test.txt","filetable":{"/data/test/ajjl.db":true,"/data/test/b.txt":true,"/data/test/zmplugin/lockbox/cipher/aes128.lua":true}}
@example:保存路径为:/storage/emulated/0/MobileAnjian/test.txt
--]=]
function SaveFileList(dirPath, savaPath)
 
    if not dirPath then
        LuaAuxLib.TracePrint("参数错误")
        return -1
    end
 
    local filetable = {}
    local rootPath = dirPath
    local cachePath
    if savaPath then
        if savaPath:find("/") then
            cachePath = savaPath
        else
            cachePath = __MQM_RUNNER_LOCAL_PATH_GLOBAL_NAME__ .. savaPath
        end
    end
    local function GetAllFiles(rootPath)
        --LuaAuxLib.TracePrint("遍历中")
        local f
        for f in lfs.dir(rootPath) do
            if f ~= '.' and f ~= '..' then
                local path = rootPath .. "/" .. f
                local attr = lfs.attributes(path)
                if type(attr) ~= "table" then
                    LuaAuxLib.TracePrint(path .. "属性获取失败")
                    return -1
                end
                if (attr.mode == "directory") then
                    GetAllFiles(path) --自调用遍历子目录
                elseif attr.mode == "file" then
                    filetable[path] = true
                end
            end
        end
    end
 
    if GetAllFiles(rootPath) == -1 then
        LuaAuxLib.TracePrint(cachePath .. "目录下的文件列表保存失败")
        return -1
    end
    if not savaPath then
        return filetable or -1
    end
    pcall(function()
        if FileWrite(cachePath, filetable) then
            return 1
        else
            cachePath = string.gsub(cachePath, "^/storage/emulated/0/", "/sdcard/", 1)
            if FileWrite(cachePath, filetable) then
                return 1
            else
                return -1
            end
        end
    end)
    if filetable then
        return { ["filepath"] = cachePath, ["filetable"] = filetable }
    else
        return -1
    end
end
QMPlugin.SaveFileList = SaveFileList
 
--[=[
@fname:CompareFileList
@cname:比较2个文本文件的内容,记录文件差异,用来检查是否添加新文件
@arg:文件路径1,文件路径2, string, 要操作的文件路径
@ret:成功返回一个table,里面有2个table,第一个为firstpath有而secondpath没有的,第二个为secondpath有而firstpath没有的
--]=]
function CompareFileList(firstpath, secondpath)
    if (not firstpath) or (not secondpath) then
        return nil
    end
    local ret1 = {}
    local ret2 = {}
    local strtable1 = {}
    local strtable2 = {}
 
    if type(firstpath) == "string" then
        strtable1 = FileReadLines(firstpath)
    elseif type(firstpath) == "table" then
        strtable1 = firstpath
    else
        return nil
    end
 
    if type(secondpath) == "string" then
        strtable2 = FileReadLines(secondpath)
    elseif type(secondpath) == "table" then
        strtable2 = secondpath
    else
        return nil
    end
    for k, _ in pairs(strtable2) do
        if not strtable1[k] then
            --LuaAuxLib.TracePrint(k)
            ret2[k] = true
            --LuaAuxLib.TracePrint(zm.VarInfo(ret1))
        else
            strtable1[k] = nil
        end
    end
    ret1 = strtable1
 
    return { ["filedelete"]=ret1,["filecreate"]=ret2 }
end
QMPlugin.CompareFileList = CompareFileList
学号3338

0

主题

1

回帖

1

积分

学前班

鲜花
0
猫粮
3
发表于 2019-5-28 08:21:24 | 显示全部楼层
VERY GOOD!非常感谢你的帮助~

0

主题

10

回帖

10

积分

按键手机班学员

鲜花
0
猫粮
64
发表于 2019-7-16 14:43:02 | 显示全部楼层
这个一定要学习一下

15

主题

30

回帖

60

积分

小学生

鲜花
0
猫粮
506
发表于 2019-7-17 10:25:52 | 显示全部楼层
很好很强大................

0

主题

12

回帖

12

积分

学前班

鲜花
0
猫粮
8
发表于 2019-7-29 11:31:54 | 显示全部楼层
很给力,学习学习感谢作者

0

主题

1

回帖

1

积分

学前班

鲜花
0
猫粮
15
发表于 2020-6-4 20:33:23 | 显示全部楼层
o(∩_∩)oo(∩_∩)oo(∩_∩)oo(∩_∩)oo(∩_∩)o

0

主题

8

回帖

8

积分

学前班

鲜花
0
猫粮
14
发表于 2020-6-17 21:43:23 | 显示全部楼层
66666666666666666

7

主题

90

回帖

104

积分

按键电脑班学员

鲜花
0
猫粮
485
QQ
发表于 2021-10-22 10:26:04 | 显示全部楼层
o(∩_∩)o

0

主题

10

回帖

10

积分

学前班

鲜花
0
猫粮
7
发表于 2021-10-29 17:11:50 | 显示全部楼层
感谢分享, 最好能提供下使用例子供新手学习
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|紫猫编程学园

GMT+8, 2024-4-28 15:15

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表