欢迎访问Ningto's博客

Menu
  • 首页
  • 归档
  • 关于
  • 书签
  • 必应壁纸
  • IT聚合
  • 工具
    • 我的工具列表
    • 我的网盘
    • 必应每日壁纸API
    • Html转Markdown
    • 仙尘光标
Menu

golang 生成目录的check list文件并校验目录

最后更新 2021-07-04 17:08:38   阅读量 1098

目的是将当前可执行程序平级的某个目录生成check list文件,表明是文件还是目录,如果是文件生成md5值。还可以根据check list文件来判断目录里面的内容是否完整,如果是目录就判断目录是否存在,如果是文件就比对md5值是否一样。

生成check list 文件:

checkfilelist.exe -name app -mode write

校验目录是否完整:

checkfilelist.exe -name app -mode check

代码如下:

package main

import (
    "bufio"
    "crypto/md5"
    "encoding/json"
    "flag"
    "fmt"
    "io"
    "io/fs"
    "os"
    "os/exec"
    "path"
    "path/filepath"
)

const CHECKLISTNAME = "checklist.json"

type DirCheck struct {
    Name  string `json:"name"`
    Items []Item
}

type Item struct {
    Type int    `json:"type"`
    Path string `json:"path"`
    Md5  string `json:"md5"`
}

func main() {
    var dirname string
    var mode string
    flag.StringVar(&dirname, "name", "", "directory name")
    flag.StringVar(&mode, "mode", "", "write or check")
    flag.Parse()

    currentfile, _ := exec.LookPath(os.Args[0])
    currentpath, _ := filepath.Abs(currentfile)
    currentdir := path.Join(currentpath, "..")
    fmt.Println("src dir:", currentdir, "name:", dirname)
    if mode == "write" {
        Write(currentdir, dirname)
        fmt.Println("write success")
    } else if mode == "check" {
        err := Check(currentdir, CHECKLISTNAME)
        if err != nil {
            panic(err)
        } else {
            fmt.Println("check success")
        }
    } else {
        panic("mode error")
    }
}

func Write(currentdir string, dirname string) {
    srcdir := path.Join(currentdir, dirname)
    fmt.Println("src dir:", srcdir)
    dc := DirCheck{}
    dc.Name = filepath.Base(srcdir)
    filepath.WalkDir(srcdir, func(pathstr string, d fs.DirEntry, err error) error {
        abspath := pathstr[len(srcdir):]
        if len(abspath) == 0 {
            return nil
        }

        filetype := 0
        md5str := ""
        if d.IsDir() {
            filetype = 1
        } else {
            filetype = 2
            md5str, err = MD5File(pathstr)
            if err != nil {
                fmt.Println("md5 error, path:", pathstr)
                panic(err)
            }
        }

        dc.Items = append(dc.Items, Item{
            Type: filetype,
            Path: abspath,
            Md5:  md5str,
        })
        fmt.Println(abspath)
        return nil
    })

    b, err := json.MarshalIndent(dc, "", "  ")
    if err != nil {
        panic(err)
    }

    if err := os.WriteFile(CHECKLISTNAME, b, os.ModePerm); err != nil {
        panic(err)
    }
}

func Check(currentdir string, name string) error {
    checklistpath := path.Join(currentdir, name)
    b, err := os.ReadFile(checklistpath)
    if err != nil {
        return err
    }

    var dc DirCheck
    if err := json.Unmarshal(b, &dc); err != nil {
        return err
    }

    for _, item := range dc.Items {
        pathstr := path.Join(currentdir, dc.Name, item.Path)
        if item.Type == 1 {
            if !FileExists(pathstr) {
                return fmt.Errorf("directory not found, dir:%s", pathstr)
            }
        } else if item.Type == 2 {
            md5str, err := MD5File(pathstr)
            if err != nil {
                return err
            }
            if md5str != item.Md5 {
                return fmt.Errorf("md5 not match, path:%s", pathstr)
            }
        }
    }
    return nil
}

func MD5File(file string) (string, error) {
    f, err := os.Open(file)
    if err != nil {
        return "", err
    }
    defer f.Close()

    r := bufio.NewReader(f)
    h := md5.New()
    _, err = io.Copy(h, r)
    if err != nil {
        return "", err
    }

    return fmt.Sprintf("%X", h.Sum(nil)), nil
}

func FileExists(path string) bool {
    _, err := os.Stat(path)
    if err != nil {
        if os.IsExist(err) {
            return true
        }
        return false
    }
    return true
}

(转载本站文章请注明作者和出处:泞途 - ningto.com)

下一篇 – 多个Qt程序共享公共库
上一篇 – Python 更新xml文件非常方便

  1. Go

toningto@outlook.com

标签云

Life Android Javascript Python Windows Product Go Tools Java MQ Qt Node.js Tips Shell Design MongoDB Others Mac Mobile React C/C++ Web Boost Linux IOS Bug Database

推广链接

【腾讯云】云产品限时秒杀,爆款1核2G云服务器,首年99元

多谢支持,用了好几年,服务很稳定支持多设备!

其他

文章RSS

Copyright © 2016 Welcome To Ningto Blog | 鄂ICP备17003086号-2