Go语言之对象存储文件对比更新
发表于 · 归类于
技术 · 阅读完需 11 分钟 ·
阅读量 报告错误
前言
对于对象存储自动化管理,文件更新工具 已经描述了在windows上自动对比更新,即检测本地和对象存储的文件列表,选择被改动或者增加的文件进行上传,但未能达到自动化管理(定时检测);以及阿里云效能够实现的把仓库文件推送到OSS的功能也存在问题(未对文件进行对比,上传多余文件),因此制作该程序可实现文件同步功能。
(1)获取阿里云OSS文件列表
func ossFileList() map[string]string {
// 创建OSSClient实例。
client, err := oss.New("http://oss-cn-hongkong.aliyuncs.com", "LTA*****toz", "MIv*****JOT")
if err != nil {
HandleError(err)
}
// 获取存储空间。
bucketName := "codepages"
bucket, err := client.Bucket(bucketName)
if err != nil {
HandleError(err)
}
// 分页列举所有文件。每页列举100个。
continueToken := ""
xcodes := make([]ObjectFile, 0)
var ossfile map[string]string
ossfile = make(map[string]string)
for {
lsRes, err := bucket.ListObjectsV2(oss.MaxKeys(300), oss.ContinuationToken(continueToken))
if err != nil {
HandleError(err)
}
xcode0 := make([]ObjectFile, len(lsRes.Objects))
// 打印列举结果。默认情况下,一次返回100条记录。
for _, object := range lsRes.Objects {
// fmt.Println(object.Key, object.Type, object.Size, strings.ToLower(object.ETag), object.LastModified, object.StorageClass)
ossfile[object.Key] = strings.ToLower(strings.Trim(object.ETag, "\""))
}
xcodes = append(xcodes, xcode0...)
if lsRes.IsTruncated {
continueToken = lsRes.NextContinuationToken
} else {
break
}
}
return ossfile
}
(2)获取本地文件列表
func localFileList(originpath string) map[string]string {
var localfile map[string]string
localfile = make(map[string]string)
filepath.Walk(originpath,
func(path string, f os.FileInfo, err error) error {
if f == nil {
return err
}
if f.IsDir() {
//fmt.Println("dir:", path)
return nil
}
// 忽略.git的目录文件
if strings.HasPrefix(path, originpath+".git") {
return nil
}
file, inerr := os.Open(path)
if inerr == nil {
md5h := md5.New()
io.Copy(md5h, file)
md5string := fmt.Sprintf("%x", md5h.Sum([]byte("")))
localfile[strings.TrimPrefix(path, originpath)] = md5string
}
return nil
})
return localfile
}
(3)更新文件至阿里云OSS
func ossUploadFile(key string, localfile string) {
// 创建OSSClient实例。
client, err := oss.New("http://oss-cn-hongkong.aliyuncs.com", "LTA*****toz", "MIv*****JOT")
if err != nil {
HandleError(err)
}
// 获取存储空间。
bucketName := "codepages"
bucket, err := client.Bucket(bucketName)
if err != nil {
HandleError(err)
}
// 自定义HTTP头部消息
options := []oss.Option{
oss.CacheControl("max-age=864000"),
}
// 上传本地文件。
err = bucket.PutObjectFromFile(key, localfile, options...)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
fmt.Println("[更新成功]", key)
}
(4)主函数调用
func main() {
originpath := "/home/wwwroot/linzening/"
lofile := localFileList(originpath)
osfile := ossFileList()
// 遍历本地
for lfile := range lofile {
// OSS不存在某个文件
if _, ok := osfile[lfile]; !ok {
// 上传文件
fmt.Println("[上传文件]", lfile)
ossUploadFile(lfile, originpath+lfile)
} else if lofile[lfile] != osfile[lfile] {
// MD5不一致,更新文件
fmt.Println("[更新文件]", lfile, lofile[lfile], osfile[lfile])
ossUploadFile(lfile, originpath+lfile)
} else {
// 文件一致,不处理
// fmt.Println("[文件正常]", lfile)
}
}
}
(5)程序实现
(6)日志记录
由于使用定时器执行程序,要把日志输出到文件中,方便后续查询日志。
logFile, err := os.OpenFile("./oss-update.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
fmt.Println("open log file failed, err:", err)
return
}
log.SetOutput(logFile)
log.Println("开始执行【" + ossBucket + "】")
(7)定时器执行
执行git代码同步本机后再执行本机同步到OSS
23 3 * * * cd /home/wwwroot/linzening/ && git pull && cd /home/wwwroot/staticfile/ && git pull && cd /data/cron/ && /data/cron/codepages && /data/cron/template-static-file
打开文件/data/cron/oss-update.log
即可查询之前的执行日志。
源代码
https://github.com/linzening/code/blob/main/go/oss-update.go