63 lines
1.1 KiB
Go
63 lines
1.1 KiB
Go
package fileutil
|
||
|
||
import (
|
||
"io"
|
||
"os"
|
||
"path/filepath"
|
||
)
|
||
|
||
// CopyFile 复制文件,保留权限
|
||
func CopyFile(src, dst string) error {
|
||
srcFile, err := os.Open(src)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer srcFile.Close()
|
||
|
||
// 确保目标目录存在
|
||
if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
|
||
return err
|
||
}
|
||
|
||
dstFile, err := os.Create(dst)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer dstFile.Close()
|
||
|
||
if _, err := io.Copy(dstFile, srcFile); err != nil {
|
||
return err
|
||
}
|
||
|
||
// 保留文件权限,移除特殊权限位(SETUID/SETGID/STICKY)
|
||
srcInfo, err := os.Stat(src)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
// 只保留标准权限位,移除特殊权限位
|
||
mode := srcInfo.Mode() & os.ModePerm
|
||
return os.Chmod(dst, mode)
|
||
}
|
||
|
||
// CopyDir 递归复制目录
|
||
func CopyDir(src, dst string) error {
|
||
return filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
relPath, err := filepath.Rel(src, path)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
dstPath := filepath.Join(dst, relPath)
|
||
|
||
if info.IsDir() {
|
||
return os.MkdirAll(dstPath, info.Mode())
|
||
}
|
||
|
||
return CopyFile(path, dstPath)
|
||
})
|
||
}
|