Files
BackupX/server/pkg/compress/zstd.go
Wu Qing 65cf3a04d4 feat(backup): 新增 zstd 压缩选项 (#89)
备份压缩在 gzip 之外新增 zstd(更高压缩率、更快解压)。pkg/compress 新增 ZstdFile/UnzstdFile,Master 与 Agent 压缩/解压按后缀分流,任务校验与前端下拉同步;往返单测覆盖。
2026-05-27 19:15:06 +08:00

66 lines
1.7 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 compress
import (
"fmt"
"io"
"os"
"strings"
"github.com/klauspost/compress/zstd"
)
// ZstdFile 将文件压缩为 .zstzstd返回压缩产物路径。
// 相比 gzipzstd 在相近 CPU 开销下提供更高压缩率与显著更快的解压速度。
func ZstdFile(sourcePath string) (string, error) {
source, err := os.Open(sourcePath)
if err != nil {
return "", fmt.Errorf("open source file: %w", err)
}
defer source.Close()
targetPath := sourcePath + ".zst"
target, err := os.Create(targetPath)
if err != nil {
return "", fmt.Errorf("create zstd file: %w", err)
}
defer target.Close()
writer, err := zstd.NewWriter(target)
if err != nil {
return "", fmt.Errorf("create zstd writer: %w", err)
}
if _, err := io.Copy(writer, source); err != nil {
_ = writer.Close()
return "", fmt.Errorf("zstd source file: %w", err)
}
if err := writer.Close(); err != nil {
return "", fmt.Errorf("close zstd writer: %w", err)
}
return targetPath, nil
}
// UnzstdFile 解压 .zst 文件,返回解压产物路径。
func UnzstdFile(sourcePath string) (string, error) {
source, err := os.Open(sourcePath)
if err != nil {
return "", fmt.Errorf("open zstd file: %w", err)
}
defer source.Close()
reader, err := zstd.NewReader(source)
if err != nil {
return "", fmt.Errorf("create zstd reader: %w", err)
}
defer reader.Close()
targetPath := strings.TrimSuffix(sourcePath, ".zst")
if targetPath == sourcePath {
targetPath += ".out"
}
target, err := os.Create(targetPath)
if err != nil {
return "", fmt.Errorf("create target file: %w", err)
}
defer target.Close()
if _, err := io.Copy(target, reader); err != nil {
return "", fmt.Errorf("unzstd file: %w", err)
}
return targetPath, nil
}