Files
backup/backup/archive.go
2026-02-02 17:19:26 +08:00

69 lines
1.5 KiB
Go

package backup
import (
"archive/tar"
"compress/gzip"
"fmt"
"io"
"os"
"path/filepath"
)
// CreateTarGz creates a tar.gz archive of the specified directory
func CreateTarGz(sourceDir, outputFile string) error {
// Create the output file
file, err := os.Create(outputFile)
if err != nil {
return fmt.Errorf("failed to create output file: %w", err)
}
defer file.Close()
// Create gzip writer
gzWriter := gzip.NewWriter(file)
defer gzWriter.Close()
// Create tar writer
tarWriter := tar.NewWriter(gzWriter)
defer tarWriter.Close()
// Walk through the source directory
return filepath.Walk(sourceDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// Create tar header
header, err := tar.FileInfoHeader(info, "")
if err != nil {
return fmt.Errorf("failed to create tar header: %w", err)
}
// Update the name to be relative to the source directory
relPath, err := filepath.Rel(sourceDir, path)
if err != nil {
return fmt.Errorf("failed to get relative path: %w", err)
}
header.Name = relPath
// Write header
if err := tarWriter.WriteHeader(header); err != nil {
return fmt.Errorf("failed to write tar header: %w", err)
}
// If it's a file, write its content
if !info.IsDir() {
file, err := os.Open(path)
if err != nil {
return fmt.Errorf("failed to open file: %w", err)
}
defer file.Close()
if _, err := io.Copy(tarWriter, file); err != nil {
return fmt.Errorf("failed to write file content: %w", err)
}
}
return nil
})
}