mirror of
https://github.com/tnb-labs/panel.git
synced 2026-08-31 01:12:17 +08:00
193 lines
3.5 KiB
Go
193 lines
3.5 KiB
Go
package io
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/TheTNB/panel/pkg/shell"
|
|
)
|
|
|
|
// Remove 删除文件/目录
|
|
func Remove(path string) error {
|
|
return os.RemoveAll(path)
|
|
}
|
|
|
|
// Mkdir 创建目录
|
|
func Mkdir(path string, permission os.FileMode) error {
|
|
return os.MkdirAll(path, permission)
|
|
}
|
|
|
|
// Chmod 修改文件/目录权限
|
|
func Chmod(path string, permission os.FileMode) error {
|
|
cmd := exec.Command("sudo", "chmod", "-R", fmt.Sprintf("%o", permission), path)
|
|
return cmd.Run()
|
|
}
|
|
|
|
// Chown 修改文件或目录所有者
|
|
func Chown(path, user, group string) error {
|
|
cmd := exec.Command("sudo", "chown", "-R", user+":"+group, path)
|
|
return cmd.Run()
|
|
}
|
|
|
|
// Exists 判断路径是否存在
|
|
func Exists(path string) bool {
|
|
_, err := os.Stat(path)
|
|
return err == nil
|
|
}
|
|
|
|
// Empty 判断路径是否为空
|
|
func Empty(path string) bool {
|
|
files, err := os.ReadDir(path)
|
|
if err != nil {
|
|
return true
|
|
}
|
|
|
|
return len(files) == 0
|
|
}
|
|
|
|
func Mv(src, dst string) error {
|
|
if err := os.Rename(src, dst); err != nil {
|
|
// 在不同的文件系统中无法使用os.Rename
|
|
if _, err = shell.Execf(`mv -f '%s' '%s'`, src, dst); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Cp 复制文件或目录
|
|
func Cp(src, dst string) error {
|
|
srcInfo, err := os.Stat(src)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if srcInfo.IsDir() {
|
|
return copyDir(src, dst)
|
|
}
|
|
return copyFile(src, dst)
|
|
}
|
|
|
|
func copyFile(src, dst string) error {
|
|
srcFile, err := os.Open(src)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer srcFile.Close()
|
|
|
|
dstFile, err := os.Create(dst)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer dstFile.Close()
|
|
|
|
_, err = io.Copy(dstFile, srcFile)
|
|
return err
|
|
}
|
|
|
|
func copyDir(src, dst string) error {
|
|
srcInfo, err := os.Stat(src)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = os.MkdirAll(dst, srcInfo.Mode())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
entries, err := os.ReadDir(src)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, entry := range entries {
|
|
srcPath := filepath.Join(src, entry.Name())
|
|
dstPath := filepath.Join(dst, entry.Name())
|
|
|
|
if entry.IsDir() {
|
|
err = copyDir(srcPath, dstPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
err = copyFile(srcPath, dstPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Size 获取路径大小
|
|
func Size(path string) (int64, error) {
|
|
var size int64
|
|
|
|
err := filepath.Walk(path, func(filePath string, info os.FileInfo, walkErr error) error {
|
|
if walkErr != nil {
|
|
return walkErr
|
|
}
|
|
size += info.Size()
|
|
return nil
|
|
})
|
|
|
|
return size, err
|
|
}
|
|
|
|
// TempDir 创建临时目录
|
|
func TempDir(prefix string) (string, error) {
|
|
return os.MkdirTemp("", prefix)
|
|
}
|
|
|
|
// TempFile 创建临时文件
|
|
func TempFile(dir, prefix string) (*os.File, error) {
|
|
return os.CreateTemp(dir, prefix)
|
|
}
|
|
|
|
// ReadDir 读取目录
|
|
func ReadDir(path string) ([]os.DirEntry, error) {
|
|
return os.ReadDir(path)
|
|
}
|
|
|
|
// IsDir 判断是否为目录
|
|
func IsDir(path string) bool {
|
|
info, err := os.Stat(path)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return info.IsDir()
|
|
}
|
|
|
|
// SizeX 获取路径大小(du命令)
|
|
func SizeX(path string) (int64, error) {
|
|
out, err := exec.Command("du", "-sb", path).Output()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
parts := strings.Fields(string(out))
|
|
if len(parts) == 0 {
|
|
return 0, fmt.Errorf("无法解析 du 输出")
|
|
}
|
|
|
|
return strconv.ParseInt(parts[0], 10, 64)
|
|
}
|
|
|
|
// CountX 统计目录下文件数
|
|
func CountX(path string) (int64, error) {
|
|
out, err := exec.Command("find", path, "-printf", ".").Output()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
count := len(string(out))
|
|
return int64(count), nil
|
|
}
|