package core import ( "io" "os" "path" "path/filepath" "scagent/config" "scagent/util" "strings" "time" "go.uber.org/zap" ) // FileService 提供文件传输服务 type FileService struct{} // FileChunk 表示文件分片 type FileChunk struct { FileName string // 文件名 Data []byte // 数据分片 Offset int64 // 偏移量,用于重组 IsLast bool // 是否为最后一个分片 } // 压缩文件 type ZipBlock struct { Curpath string // 当前路径 SelFile []string // 选中的文件 } // Upload 接收文件分片并写入到本地文件 func (f *FileService) Upload(chunk FileChunk, reply *bool) error { // 打开或创建文件,使用追加模式 file, err := os.OpenFile(chunk.FileName, os.O_WRONLY|os.O_CREATE, 0644) if err != nil { return err } defer file.Close() // 移动到指定偏移量 if _, err := file.Seek(chunk.Offset, io.SeekStart); err != nil { return err } // 写入数据 if _, err := file.Write(chunk.Data); err != nil { return err } *reply = true return nil } // 压缩文件 // 返回压缩包的名称 func (f *FileService) Compress(args *ZipBlock, reply *string) error { // 启用日志 logger := util.NewProductionLogger() defer logger.Sync() // 实际路径 realFilePath := filepath.Join(config.G.FilePath, args.Curpath) // zip 文件名 zpFileName := "BIU_" + time.Now().Format("20060102_150405") + ".zip" // 创建zip 异步? taskId := make(chan string) // 异步压缩 go func() { util.CompressToZip(zpFileName, realFilePath, args.SelFile) taskId <- "arcok" // 日志输出 logger.Info("压缩文件", zap.String("filename", zpFileName), zap.String("path", realFilePath)) }() // ZIP 文件的实际路径 ziprl := path.Join("./sync_zips/", zpFileName) // zip 创建成功后 rest := <-taskId // 如果压缩包生成成功以后再执行 if strings.EqualFold(strings.ToLower(rest), "arcok") { // 返回压缩包名称 *reply = ziprl } return nil }