Files
be.ems/src/modules/crontask/processor/removeFile/removeFile.go

160 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package removeFile
import (
"encoding/json"
"os"
"path/filepath"
"sort"
"time"
"be.ems/lib/log"
"be.ems/src/framework/cron"
)
var NewProcessor = &BarProcessor{
progress: 0,
count: 0,
}
// bar 队列任务处理
type BarProcessor struct {
// 任务进度
progress int
// 执行次数
count int
}
type BarParams struct {
FilePath string `json:"filePath"` // file path
MaxDays int `json:"maxDays"`
MaxFiles *int `json:"maxFiles"` // keep max files
MaxSize *int64 `json:"maxSize"`
Extras string `json:"extras"` // extras condition for where
}
type FileInfo struct {
Path string
Info os.FileInfo
}
func (s *BarProcessor) Execute(data any) (any, error) {
s.count++
options := data.(cron.JobData)
sysJob := options.SysJob
var params []BarParams
err := json.Unmarshal([]byte(sysJob.TargetParams), &params)
if err != nil {
return nil, err
}
result := []map[string]any{}
for _, param := range params {
res, _ := s.ExecuteOne(param)
result = append(result, res)
}
// 返回结果,用于记录执行结果
return map[string]any{
"result": result,
}, nil
}
func (s *BarProcessor) ExecuteOne(params BarParams) (map[string]any, error) {
var maxFiles int = 0
var maxSize int64 = 0
if params.MaxFiles != nil {
maxFiles = *params.MaxFiles
}
if params.MaxSize != nil {
maxSize = int64(*params.MaxSize * 1024 * 1024)
}
files, err := getFiles(params.FilePath)
if err != nil {
return map[string]any{
"msg": "failed",
"err": err.Error(),
}, err
}
// 获取本地时区
loc, err := time.LoadLocation("Local")
if err != nil {
return map[string]any{
"msg": "failed",
"err": err.Error(),
}, err
}
cutoff := time.Now().In(loc).AddDate(0, 0, -params.MaxDays)
var oldFiles []FileInfo
for _, file := range files {
if file.Info.ModTime().Before(cutoff) {
oldFiles = append(oldFiles, file)
}
}
// 按修改时间排序文件(最旧的在前)
sort.Slice(oldFiles, func(i, j int) bool {
return oldFiles[i].Info.ModTime().Before(oldFiles[j].Info.ModTime())
})
deleted, errorDel := 0, 0
// 删除文件直到满足文件总数不超过maxFiles个且总大小不超过maxSize的条件
var totalSize int64
for i, file := range oldFiles {
if (maxFiles > 0 && i >= maxFiles) || (maxSize > 0 && totalSize+file.Info.Size() > maxSize) {
break
}
err := os.Remove(file.Path)
if err != nil {
log.Error("Error deleting file:", file.Path, err)
errorDel++
continue
}
totalSize += file.Info.Size()
deleted++
}
// 如果仍然有超过maxFiles个文件或总大小超过maxSize继续删除最旧的文件
remainingFiles := files
sort.Slice(remainingFiles, func(i, j int) bool {
return remainingFiles[i].Info.ModTime().Before(remainingFiles[j].Info.ModTime())
})
for (maxFiles > 0 && len(remainingFiles) > maxFiles) || (maxSize > 0 && totalSize > maxSize) {
file := remainingFiles[0]
err := os.Remove(file.Path)
if err != nil {
log.Error("Error deleting file:", file.Path, err)
remainingFiles = remainingFiles[1:]
continue
}
totalSize -= file.Info.Size()
remainingFiles = remainingFiles[1:]
}
// 返回结果,用于记录执行结果
return map[string]any{
"msg": "successed",
"filePath": params.FilePath,
"deleted": deleted,
"errorDel": errorDel,
}, nil
}
func getFiles(dir string) ([]FileInfo, error) {
var files []FileInfo
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
files = append(files, FileInfo{Path: path, Info: info})
}
return nil
})
return files, err
}