mirror of https://gitee.com/godoos/godoos.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
235 lines
5.0 KiB
235 lines
5.0 KiB
/*
|
|
* GodoOS - A lightweight cloud desktop
|
|
* Copyright (C) 2024 https://godoos.com
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 2.1 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package files
|
|
|
|
import (
|
|
"archive/tar"
|
|
"archive/zip"
|
|
"compress/gzip"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
// 压缩文件到指定的目录
|
|
func zipCompress(folderPath, zipFilePath string) error {
|
|
zipFile, err := os.Create(zipFilePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer zipFile.Close()
|
|
|
|
zipWriter := zip.NewWriter(zipFile)
|
|
defer zipWriter.Close()
|
|
|
|
info, err := os.Stat(folderPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var baseDir string
|
|
if info.IsDir() {
|
|
baseDir = filepath.Base(folderPath)
|
|
}
|
|
|
|
filepath.Walk(folderPath, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
header, err := zip.FileInfoHeader(info)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
relPath, err := filepath.Rel(folderPath, path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if baseDir != "" {
|
|
header.Name = filepath.Join(baseDir, relPath)
|
|
} else {
|
|
header.Name = relPath
|
|
}
|
|
|
|
if info.IsDir() {
|
|
header.Name += "/"
|
|
} else {
|
|
header.Method = zip.Deflate
|
|
}
|
|
|
|
writer, err := zipWriter.CreateHeader(header)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if info.IsDir() {
|
|
return nil
|
|
}
|
|
|
|
file, err := os.Open(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
|
|
_, err = io.Copy(writer, file)
|
|
return err
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
// IsSupportedCompressionFormat 判断文件后缀是否为支持的压缩格式
|
|
func IsSupportedFormat(filename string) bool {
|
|
supportedFormats := map[string]bool{
|
|
".zip": true,
|
|
".tar": true,
|
|
".gz": true,
|
|
}
|
|
|
|
for format := range supportedFormats {
|
|
if strings.HasSuffix(strings.ToLower(filename), format) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// CompressFileOrFolder 压缩文件或文件夹到指定的压缩文件
|
|
func CompressFileOrFolder(sourcePath, compressedFilePath string) error {
|
|
if IsSupportedFormat(compressedFilePath) {
|
|
return Encompress(sourcePath, compressedFilePath)
|
|
}
|
|
// 如果压缩文件格式不受支持,则返回错误或采取其他措施
|
|
return fmt.Errorf("unsupported compression format for file: %s", compressedFilePath)
|
|
}
|
|
|
|
// Encompress 压缩文件或文件夹到指定的压缩格式
|
|
func Encompress(sourcePath, compressedFilePath string) error {
|
|
switch filepath.Ext(compressedFilePath) {
|
|
case ".zip":
|
|
return zipCompress(sourcePath, compressedFilePath)
|
|
case ".tar":
|
|
return tarCompress(sourcePath, compressedFilePath)
|
|
case ".gz":
|
|
return tarGzCompress(sourcePath, compressedFilePath)
|
|
default:
|
|
return fmt.Errorf("unsupported compression format: %s", filepath.Ext(compressedFilePath))
|
|
}
|
|
}
|
|
|
|
// tarCompress 使用 tar 格式压缩文件或文件夹
|
|
func tarCompress(folderPath, tarFilePath string) error {
|
|
// 打开目标文件
|
|
tarFile, err := os.Create(tarFilePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer tarFile.Close()
|
|
|
|
// 创建 tar.Writer
|
|
tarWriter := tar.NewWriter(tarFile)
|
|
defer tarWriter.Close()
|
|
|
|
// 遍历文件夹并添加到 tar 文件
|
|
err = filepath.Walk(folderPath, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
header, err := tar.FileInfoHeader(info, "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := tarWriter.WriteHeader(header); err != nil {
|
|
return err
|
|
}
|
|
|
|
if !info.IsDir() {
|
|
file, err := os.Open(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
|
|
_, err = io.Copy(tarWriter, file)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
|
|
return err
|
|
}
|
|
|
|
// tarGzCompress 使用 tar.gz 格式压缩文件或文件夹
|
|
func tarGzCompress(folderPath, tarGzFilePath string) error {
|
|
// 打开目标文件
|
|
gzFile, err := os.Create(tarGzFilePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer gzFile.Close()
|
|
|
|
// 创建 gzip.Writer
|
|
gzWriter := gzip.NewWriter(gzFile)
|
|
defer gzWriter.Close()
|
|
|
|
// 创建 tar.Writer
|
|
tarWriter := tar.NewWriter(gzWriter)
|
|
defer tarWriter.Close()
|
|
|
|
// 遍历文件夹并添加到 tar 文件
|
|
err = filepath.Walk(folderPath, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
header, err := tar.FileInfoHeader(info, "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := tarWriter.WriteHeader(header); err != nil {
|
|
return err
|
|
}
|
|
|
|
if !info.IsDir() {
|
|
file, err := os.Open(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
|
|
_, err = io.Copy(tarWriter, file)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
|
|
return err
|
|
}
|
|
|