紫猫学院社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1307|回复: 6

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

[复制链接]

2

主题

8

帖子

8

积分

按键电脑&手机班学员

Rank: 8Rank: 8

猫粮
66
发表于 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"]))


结果类似:





源码:
[按键精灵] 纯文本查看 复制代码
--[=[
@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


本帖子中包含更多资源

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

x
学号3338
回复

使用道具 举报

2

主题

8

帖子

8

积分

按键电脑&手机班学员

Rank: 8Rank: 8

猫粮
66
 楼主| 发表于 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

积分

学前班

Rank: 1

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

使用道具 举报

0

主题

10

帖子

10

积分

按键手机班学员

Rank: 8Rank: 8

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

使用道具 举报

13

主题

39

帖子

39

积分

小学生

Rank: 2

猫粮
297
发表于 2019-7-17 10:25:52 | 显示全部楼层
很好很强大................
回复

使用道具 举报

0

主题

12

帖子

12

积分

学前班

Rank: 1

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

使用道具 举报

0

主题

1

帖子

1

积分

学前班

Rank: 1

猫粮
6
发表于 3 天前 | 显示全部楼层
o(∩_∩)oo(∩_∩)oo(∩_∩)oo(∩_∩)oo(∩_∩)o
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2020-6-7 13:23

Powered by Discuz! X3.4

Copyright © 2012-2020 紫猫编程学院

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