package util import ( "cicv-data-closedloop/kinglong/common/log" "cicv-data-closedloop/pji/common/cfg" "cicv-data-closedloop/pji/common/ent" "cicv-data-closedloop/pji/common/global" "fmt" "os" "os/exec" "path/filepath" "sort" "strconv" "strings" "time" ) // AppendIfNotExists 向切片中追加元素,如果元素已存在则不添加 func AppendIfNotExists(slice []string, element string) []string { for _, item := range slice { if item == element { return slice // 元素已存在,直接返回原切片 } } return append(slice, element) // 元素不存在,追加到切片末尾 } func AddTimeWindowToTimeWindowProducerQueue(window ent.TimeWindow) { global.TimeWindowProducerQueueMutex.RLock() { global.TimeWindowProducerQueue = append(global.TimeWindowProducerQueue, window) } global.TimeWindowProducerQueueMutex.RUnlock() } func AddTimeWindowToTimeWindowConsumerQueue(window ent.TimeWindow) { global.TimeWindowConsumerQueueMutex.RLock() { global.TimeWindowConsumerQueue = append(global.TimeWindowConsumerQueue, window) } global.TimeWindowConsumerQueueMutex.RUnlock() } func RemoveHeaOfdTimeWindowProducerQueue() { global.TimeWindowProducerQueueMutex.RLock() { global.TimeWindowProducerQueue = global.TimeWindowProducerQueue[1:] } global.TimeWindowProducerQueueMutex.RUnlock() } func RemoveHeaOfdTimeWindowConsumerQueue() { global.TimeWindowConsumerQueueMutex.RLock() { global.TimeWindowConsumerQueue = global.TimeWindowConsumerQueue[1:] } global.TimeWindowConsumerQueueMutex.RUnlock() } func GetBagTime(bagName string) string { s1 := strings.Split(bagName, "_")[0] s1Split := strings.Split(s1, "/") s2 := s1Split[len(s1Split)-1] return s2 } func TimeCustomChange(originalTimeStr string, number int) string { var newTimeStr string // 解析时间字符串 layout := "2006-01-02-15-04-05" originalTime, err := time.Parse(layout, originalTimeStr) if err != nil { log.GlobalLogger.Info("无法解析时间字符串:", err) return newTimeStr } // 减少1秒 newTime := originalTime.Add(time.Duration(number) * time.Second) // 格式化新的时间为指定字符串格式 return newTime.Format(layout) } func CalculateDifferenceOfTimeCustom(timeCustom1 string, timeCustom2 string) int { timeInt1, _ := strconv.Atoi(strings.Replace(timeCustom1, "-", "", -1)) timeInt2, _ := strconv.Atoi(strings.Replace(timeCustom2, "-", "", -1)) return timeInt2 - timeInt1 + 1 } func TimeCustom1GreaterTimeCustom2(timeCustom1 string, timeCustom2 string) bool { timeInt1, _ := strconv.Atoi(strings.Replace(timeCustom1, "-", "", -1)) timeInt2, _ := strconv.Atoi(strings.Replace(timeCustom2, "-", "", -1)) return timeInt1 > timeInt2 } func TimeCustom1GreaterEqualThanTimeCustom2(timeCustom1 string, timeCustom2 string) bool { timeInt1, _ := strconv.Atoi(strings.Replace(timeCustom1, "-", "", -1)) timeInt2, _ := strconv.Atoi(strings.Replace(timeCustom2, "-", "", -1)) return timeInt1 >= timeInt2 } func TimeCustom1LessEqualThanTimeCustom2(timeCustom1 string, timeCustom2 string) bool { timeInt1, _ := strconv.Atoi(strings.Replace(timeCustom1, "-", "", -1)) timeInt2, _ := strconv.Atoi(strings.Replace(timeCustom2, "-", "", -1)) return timeInt1 <= timeInt2 } func Hex(num int) string { return fmt.Sprintf("0x%x", num) } // GetDiskUsagePercent 获取磁盘使用率 func GetDiskUsagePercent() float64 { // 执行 df 命令获取磁盘使用情况 cmd := exec.Command("df", "--total") output, err := cmd.Output() if err != nil { log.GlobalLogger.Info("执行命令失败:", err) return 0.0 } // 解析 df 命令输出,计算磁盘占比 lines := strings.Split(string(output), "\n") for _, line := range lines[1:] { fields := strings.Fields(line) if len(fields) >= 6 && fields[0] == "total" { //filesystem := fields[0] total, _ := strconv.ParseFloat(strings.TrimSuffix(fields[1], "G"), 64) used, _ := strconv.ParseFloat(strings.TrimSuffix(fields[2], "G"), 64) usedPercent := (used / total) * 100 //fmt.Printf("文件系统 %s 已使用 %.2f%%\n", filesystem, usedPercent) return usedPercent } } return 0.0 } func ListAbsolutePathAndSort(dir string) []string { var result []string if !strings.HasSuffix(dir, "/") { dir = dir + "/" } files, err := os.ReadDir(dir) if err != nil { log.GlobalLogger.Info("获取文件列表失败:", err) return result } for _, file := range files { result = append(result, dir+file.Name()) } // 根据文件名进行升序排序 sort.Slice(result, func(i, j int) bool { return filepath.Base(result[i]) < filepath.Base(result[j]) }) return result } func GetCopyDir(faultTime string) string { return cfg.CloudConfig.BagCopyDir + faultTime + "/" } func MergeSlice(slice1 []string, slice2 []string) []string { // 遍历第二个切片中的元素,并去重追加到结果切片1中 for _, element := range slice2 { found := false for _, item := range slice1 { if element == item { found = true break } } if !found { slice1 = append(slice1, element) } } return slice1 } func DeleteFile(path string) { // 检查文件是否存在 if _, err := os.Stat(path); err == nil { // 文件存在,执行删除操作 err := os.Remove(path) if err != nil { fmt.Printf("删除文件时发生错误:%s\n", err) return } } } // GetLastTimeWindow 获取最后一个时间窗口 func GetLastTimeWindow() *ent.TimeWindow { var lastTimeWindow *ent.TimeWindow // 获取最后一个时间窗口 if len(global.TimeWindowProducerQueue) > 0 { lastTimeWindow = &global.TimeWindowProducerQueue[len(global.TimeWindowProducerQueue)-1] } return lastTimeWindow } // SupplyCopyBags 如果 Copy目录下的包不够,则补充一些 func SupplyCopyBags(currentTimeWindow ent.TimeWindow) { // 如果bag包没有达到length,补充几个 copyBags, _ := ListAbsolutePathWithSuffixAndSort(GetCopyDir(currentTimeWindow.FaultTime), ".bag") copyBagsLength := len(copyBags) if copyBagsLength < currentTimeWindow.Length { time.Sleep(time.Duration(copyBagsLength) * time.Second) dataBags, _ := ListAbsolutePathWithSuffixAndSort(cfg.CloudConfig.BagDataDir, ".bag") gap := currentTimeWindow.Length - copyBagsLength log.GlobalLogger.Info("故障 ", currentTimeWindow.FaultTime, "需要补充 ", gap, " 个 bag 包") for _, bag := range dataBags { bagTime := GetBagTime(bag) if TimeCustom1GreaterEqualThanTimeCustom2(bagTime, currentTimeWindow.FaultTime) { MoveFromDataToCopy(currentTimeWindow.FaultTime, bag) gap = gap - 1 if gap == 0 { break } } } } }