mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 22:07:16 +08:00
247 lines
4.6 KiB
Go
247 lines
4.6 KiB
Go
package tools
|
||
|
||
import (
|
||
"bytes"
|
||
"errors"
|
||
"fmt"
|
||
"io"
|
||
"os"
|
||
"os/exec"
|
||
"path/filepath"
|
||
"strings"
|
||
|
||
"github.com/goravel/framework/support"
|
||
"github.com/goravel/framework/support/env"
|
||
"github.com/mholt/archiver/v3"
|
||
)
|
||
|
||
// Write 写入文件
|
||
func Write(path string, data string, permission os.FileMode) error {
|
||
if err := os.MkdirAll(filepath.Dir(path), permission); err != nil {
|
||
return err
|
||
}
|
||
|
||
err := os.WriteFile(path, []byte(data), permission)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// Read 读取文件
|
||
func Read(path string) (string, error) {
|
||
data, err := os.ReadFile(path)
|
||
return string(data), err
|
||
}
|
||
|
||
// Remove 删除文件/目录
|
||
func Remove(path string) error {
|
||
return os.RemoveAll(path)
|
||
}
|
||
|
||
// Exec 执行 shell 命令
|
||
func Exec(shell string) (string, error) {
|
||
var cmd *exec.Cmd
|
||
if env.IsLinux() {
|
||
cmd = exec.Command("bash", "-c", "LC_ALL=C "+shell)
|
||
} else {
|
||
cmd = exec.Command("cmd", "/C", "chcp 65001 >nul && "+shell)
|
||
}
|
||
|
||
var stdoutBuf, stderrBuf bytes.Buffer
|
||
cmd.Stdout = &stdoutBuf
|
||
cmd.Stderr = &stderrBuf
|
||
|
||
err := cmd.Run()
|
||
if err != nil {
|
||
return "", errors.New(strings.TrimSpace(stderrBuf.String()))
|
||
}
|
||
|
||
return strings.TrimSpace(stdoutBuf.String()), err
|
||
}
|
||
|
||
// ExecAsync 异步执行 shell 命令
|
||
func ExecAsync(shell string) error {
|
||
var cmd *exec.Cmd
|
||
if env.IsLinux() {
|
||
cmd = exec.Command("bash", "-c", "LC_ALL=C "+shell)
|
||
} else {
|
||
cmd = exec.Command("cmd", "/C", "chcp 65001 >nul && "+shell)
|
||
}
|
||
|
||
err := cmd.Start()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
go func() {
|
||
err := cmd.Wait()
|
||
if err != nil {
|
||
if support.Env == support.EnvTest {
|
||
fmt.Println(err.Error())
|
||
panic(err)
|
||
}
|
||
}
|
||
}()
|
||
|
||
return nil
|
||
}
|
||
|
||
// Mkdir 创建目录
|
||
func Mkdir(path string, permission os.FileMode) error {
|
||
return os.MkdirAll(path, permission)
|
||
}
|
||
|
||
// Chmod 修改文件/目录权限
|
||
func Chmod(path string, permission os.FileMode) error {
|
||
return os.Chmod(path, permission)
|
||
}
|
||
|
||
// Chown 修改文件或目录所有者
|
||
func Chown(path, user, group string) error {
|
||
if env.IsWindows() {
|
||
return errors.New("chown is not supported on Windows")
|
||
}
|
||
|
||
cmd := exec.Command("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 {
|
||
err := os.Rename(src, dst)
|
||
if err != nil {
|
||
// 如果在不同的文件系统中移动文件,os.Rename 可能会失败
|
||
// 在这种情况下,可以先复制然后删除原文件
|
||
if os.IsExist(err) {
|
||
err = Cp(src, dst)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
err = os.RemoveAll(src)
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
// 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
|
||
}
|
||
|
||
// FileInfo 获取文件大小
|
||
func FileInfo(path string) (os.FileInfo, error) {
|
||
return os.Stat(path)
|
||
}
|
||
|
||
// UnArchive 智能解压文件
|
||
func UnArchive(file string, dst string) error {
|
||
return archiver.Unarchive(file, dst)
|
||
}
|
||
|
||
// Archive 智能压缩文件
|
||
func Archive(src []string, dst string) error {
|
||
return archiver.Archive(src, dst)
|
||
}
|
||
|
||
// TempDir 创建临时目录
|
||
func TempDir(prefix string) (string, error) {
|
||
return os.MkdirTemp("", prefix)
|
||
}
|
||
|
||
// TempFile 创建临时文件
|
||
func TempFile(prefix string) (*os.File, error) {
|
||
return os.CreateTemp("", prefix)
|
||
}
|