Releases: IBAS0742/kaoyan
Releases · IBAS0742/kaoyan
文件备份工具
大概的使用方法如下
使用方法: sync [-tar=] [-from=] [-to=] [-help=] [-exclude=]
Options:
-exclude string
排除文件,只在 [tar=dir] 时有效
-from string
源文件位置
-help
帮助文档
-tar string
file 或 dir 表示同步的文件是[文件]或[文件夹]
-to string
同步到的位置
exclude 是指定一个文件,文件中每行对应一个文件夹路径
例如 sync -t dir -f d:\a -t e:\a -e d:\a\exclude.txt
d:\a\exclude.txt 内容如下三行时
path=.git
path=.idea
exte=.exe
-
备份时,通过检查文件 MD5 的值来判断一个文件是否需要被覆盖
-
代码如下
package main
import (
"crypto/md5"
"errors"
"flag"
"fmt"
"io"
"os"
"strconv"
"strings"
"sunibas.cn/go_utils/utils/DirAndFile"
)
var (
tar string
pathFrom string
pathTo string
help bool
ok bool
errMessage string
excludeFile string
excludePath []string
excludeExt []string
)
func usage() {
if len(errMessage) != 0 {
fmt.Fprint(os.Stderr,"参数错误\r\n" + errMessage)
}
fmt.Fprintf(os.Stderr, `sync_ibas version: sync/1.0.0
使用方法: sync_ibas [-tar=] [-from=] [-to=] [-help=] [-exclude=]
Options:
`)
flag.PrintDefaults()
fmt.Fprintf(os.Stderr, `
exclude 是指定一个文件,文件中每行对应一个文件夹路径
例如 sync_ibas -t dir -f d:\a -t e:\a -e d:\a\exclude.txt
d:\a\exclude.txt 内容如下三行时
path=.git
path=.idea
exte=.exe
将不会复制 [d:\a\.git] 和 [d:\a\.idea] 两个文件夹和以 [.exe] 结尾的文件
`);
}
func init() () {
ok = true
flag.StringVar(&tar,"tar","","file 或 dir 表示同步的文件是[文件]或[文件夹]")
flag.StringVar(&pathFrom,"from","","源文件位置")
flag.StringVar(&pathTo,"to","","同步到的位置")
flag.BoolVar(&help,"help",false,"帮助文档")
flag.StringVar(&excludeFile,"exclude","","排除文件,只在 [tar=dir] 时有效")
flag.Usage = usage
}
func checkArgs() {
if help {
ok = false
} else {
if tar != "file" && tar != "dir" {
ok = false
errMessage += "tar 是必要的\r\n"
}
if pathFrom == "" {
errMessage += "from 是必要的\r\n"
}
if pathTo == "" {
errMessage += "to 是必要的\r\n"
}
}
}
func getMd5(fpath string) string {
f, err := os.Open(fpath)
if err != nil {
fmt.Println("Open", err)
return ""
}
defer f.Close()
md5hash := md5.New()
if _, err := io.Copy(md5hash, f); err != nil {
fmt.Println("Copy", err)
return ""
}
x := md5hash.Sum(nil)
md5_s := ""
for _,b := range x {
md5_s += strconv.FormatInt(int64(b),16)
}
//md5hash.Sum(nil)
return md5_s
}
func main() {
flag.Parse()
checkArgs()
if !ok {
flag.Usage()
} else {
if tar == "file" {
syncFile(pathFrom,pathTo)
} else {
syncDir()
}
}
//md5_0 := getMd5("D:\\codes\\文档\\HP C3000刀片机操作.docx")
//md5_1 := getMd5("D:\\codes\\文档\\77ce515f9cf940daf72da6c30e5e7cb.jpg")
//md5_2 := getMd5("Z:\\jiayu\\文档\\77ce515f9cf940daf72da6c30e5e7cb.jpg")
}
func checkFileExist(filePath string) (bool,error) {
if t,e := DirAndFile.PathExistsAndType(filePath);
e == nil {
if t == DirAndFile.File {
return true,nil
} else if t == DirAndFile.NoExist {
return false,nil
} else {
return false,errors.New("不是文件")
}
} else {
return false,e
}
}
func syncFile(from,to string) {
fmt.Printf("开始尝试将[%s]同步到[%s]\r\n",from,to)
if exist,err := checkFileExist(from);err == nil {
if exist {
if exist1,err1 := checkFileExist(to);err1 == nil {
// 文件存在则判断 md5,不存在则直接复制即可
if exist1 {
fmt.Printf("文件[%s]存在",to)
md5_0 := getMd5(from)
md5_1 := getMd5(to)
// md5 一致则事情完成
if md5_1 == md5_0 {
fmt.Printf(",并且 md5 一致,不需要同步\r\n")
return
} else {
fmt.Printf(",并且 md5 不一致")
}
// md5 不一致,直接删掉然后 if 外直接复制即可
err2 := os.Remove(to)
if err2 != nil {
fmt.Printf("删除 [%s] 发生错误\r\n%s\r\n", to, err1.Error())
}
} else {
fmt.Printf("文件[%s]不存在",to)
}
fmt.Printf(",开始复制文件\r\n")
DirAndFile.CopyFile(from,to)
fmt.Printf(",文件[%s]复制完成\r\n",to)
} else {
fmt.Printf("文件 [%s] 有问题\r\n%s\r\n",to,err1.Error())
}
} else {
fmt.Printf("文件 [%s] 不存在",from)
}
} else {
fmt.Printf("文件 [%s] 有问题\r\n%s\r\n",from,err.Error())
}
}
// 在路径结尾加 / 或 \
func toRightPath() {
rep := "\\"
if DirAndFile.Filepath_Separator == "\\" {
rep = "/"
}
pathFrom = strings.Replace(pathFrom,rep,DirAndFile.Filepath_Separator,-1)
sp := pathFrom[len(pathFrom) - 1]
if sp != DirAndFile.Filepath_Separator[0] {
pathFrom += DirAndFile.Filepath_Separator
}
pathTo = strings.Replace(pathTo,rep,DirAndFile.Filepath_Separator,-1)
sp = pathTo[len(pathTo) - 1]
if sp != DirAndFile.Filepath_Separator[0] {
pathTo += DirAndFile.Filepath_Separator
}
}
func checkPath() error {
if t,e := DirAndFile.PathExistsAndType(pathFrom);
nil == e {
if t != DirAndFile.Dir {
return errors.New(pathFrom + "不存在或不是文件夹")
} else {
if t1,e1 := DirAndFile.PathExistsAndType(pathTo);
nil == e1 {
if (t1 == DirAndFile.File) {
return errors.New(pathTo + "不能是一个文件夹")
} else if (t1 == DirAndFile.Dir) {
return nil
} else {
os.Mkdir(pathTo,os.ModePerm)
return nil
}
} else {
return e1
}
}
} else {
return e
}
}
func checkPathAndCreate(npath string) error {
if t1,e1 := DirAndFile.PathExistsAndType(npath);
nil == e1 {
if (t1 == DirAndFile.File) {
return errors.New(npath + "不能是一个文件夹")
} else if (t1 == DirAndFile.Dir) {
return nil
} else {
os.Mkdir(npath,os.ModePerm)
return nil
}
} else {
return e1
}
}
func readExcludeFile() {
if len(excludeFile) != 0 {
if exist,err := checkFileExist(excludeFile);err == nil {
if exist {
excludePath = DirAndFile.ReadAsFileAsLine(excludeFile)
for ind,ep := range excludePath {
if len(ep) > 5 && ep[0:5] == "path=" {
excludePath[ind] = pathFrom + ep[5:]
} else if len(ep) > 5 && ep[0:5] == "exte=" {
excludeExt = append(excludeExt,ep[5:])
}
}
} else {
fmt.Fprint(os.Stderr,"exclude [%s] 文件不存在\r\n",excludeFile)
}
} else {
fmt.Fprint(os.Stderr,"读取 exclude [%s] 文件出错\r\n%s\r\n",excludeFile,err.Error())
}
}
}
func syncDir() {
if err := checkPath();err != nil {
fmt.Print(err.Error())
return
}
toRightPath()
readExcludeFile()
fs,_ := DirAndFile.FilePathWalkDir(pathFrom)
for _,f := range fs {
if f.File {
if f.Name[0] == '~' { continue }
nfile := pathTo + f.RPath
fok := true
for _,ep := range excludePath {
if len(f.FullPath) >= len(ep) && f.FullPath[0:len(ep)] == ep {
fok = false
break
}
}
if fok {
for _,ee := range excludeExt {
if len(f.Name) > len(ee) && f.Name[len(f.Name) - len(ee):] == ee {
fok = false
break
}
}
}
if fok {
syncFile(f.FullPath,nfile)
} else {
fmt.Printf("文件[%s]被排除\r\n",nfile)
}
} else {
npath := pathTo + f.RPath
fok := true
for _,ep := range excludePath {
if len(f.FullPath) >= len(ep) && f.FullPath[0:len(ep)] == ep {
fok = false
break
}
}
if fok {
if cpacErr := checkPathAndCreate(npath);cpacErr != nil {
fmt.Fprintf(os.Stderr,"检查路径[%s]发生错误\r\n%s\r\n",npath,cpacErr.Error())
excludePath = append(excludePath,npath)
}
}
}
}
}
F-Secure Freedome VPN 2.28.5979.0.exe
一个超快的梯子
试用5天后重新安装即可
getPrj
redis desktop
redis 可视化管理工具
好像是被下架了
没安装,现在没有截图可以提供,应该还是能用的吧