在go中复制文件夹
有没有一种简单的方法可以在go中复制目录? 我有以下功能:在go中复制文件夹,go,copy,directory,Go,Copy,Directory,有没有一种简单的方法可以在go中复制目录? 我有以下功能: err = CopyDir("sourceFolder","destinationFolder") 到目前为止,任何东西都不起作用,包括github.com/cf-guardian/guardian/kernel/fileutils等库 需要注意的一点是,我需要保留目录结构,包括sourceFolder本身,而不是简单地复制文件夹的所有内容。似乎正是您想要做的,试试看 自述文件: err := Copy("your/source/di
err = CopyDir("sourceFolder","destinationFolder")
到目前为止,任何东西都不起作用,包括github.com/cf-guardian/guardian/kernel/fileutils等库
需要注意的一点是,我需要保留目录结构,包括sourceFolder本身,而不是简单地复制文件夹的所有内容。似乎正是您想要做的,试试看
自述文件:
err := Copy("your/source/directory", "your/destination/directory")
我相信docker实施可以被视为处理边缘案例的完整解决方案: 有以下几件好事:
- 不支持的文件类型上升错误
- 保留权限和所有权
- 保留扩展属性
- 保留时间戳
func CopyDirectory(scrDir, dest string) error {
entries, err := ioutil.ReadDir(scrDir)
if err != nil {
return err
}
for _, entry := range entries {
sourcePath := filepath.Join(scrDir, entry.Name())
destPath := filepath.Join(dest, entry.Name())
fileInfo, err := os.Stat(sourcePath)
if err != nil {
return err
}
stat, ok := fileInfo.Sys().(*syscall.Stat_t)
if !ok {
return fmt.Errorf("failed to get raw syscall.Stat_t data for '%s'", sourcePath)
}
switch fileInfo.Mode() & os.ModeType{
case os.ModeDir:
if err := CreateIfNotExists(destPath, 0755); err != nil {
return err
}
if err := CopyDirectory(sourcePath, destPath); err != nil {
return err
}
case os.ModeSymlink:
if err := CopySymLink(sourcePath, destPath); err != nil {
return err
}
default:
if err := Copy(sourcePath, destPath); err != nil {
return err
}
}
if err := os.Lchown(destPath, int(stat.Uid), int(stat.Gid)); err != nil {
return err
}
isSymlink := entry.Mode()&os.ModeSymlink != 0
if !isSymlink {
if err := os.Chmod(destPath, entry.Mode()); err != nil {
return err
}
}
}
return nil
}
func Copy(srcFile, dstFile string) error {
out, err := os.Create(dstFile)
if err != nil {
return err
}
defer out.Close()
in, err := os.Open(srcFile)
defer in.Close()
if err != nil {
return err
}
_, err = io.Copy(out, in)
if err != nil {
return err
}
return nil
}
func Exists(filePath string) bool {
if _, err := os.Stat(filePath); os.IsNotExist(err) {
return false
}
return true
}
func CreateIfNotExists(dir string, perm os.FileMode) error {
if Exists(dir) {
return nil
}
if err := os.MkdirAll(dir, perm); err != nil {
return fmt.Errorf("failed to create directory: '%s', error: '%s'", dir, err.Error())
}
return nil
}
func CopySymLink(source, dest string) error {
link, err := os.Readlink(source)
if err != nil {
return err
}
return os.Symlink(link, dest)
}
我想出了一个相对较短的答案,它使用了
path/filepath
的Walk
方法:
import (
"io/ioutil"
"path/filepath"
"os"
"strings"
)
func copy(source, destination string) error {
var err error = filepath.Walk(source, func(path string, info os.FileInfo, err error) error {
var relPath string = strings.Replace(path, source, "", 1)
if relPath == "" {
return nil
}
if info.IsDir() {
return os.Mkdir(filepath.Join(destination, relPath), 0755)
} else {
var data, err1 = ioutil.ReadFile(filepath.Join(source, relPath))
if err1 != nil {
return err1
}
return ioutil.WriteFile(filepath.Join(destination, relPath), data, 0777)
}
})
return err
}
此外,这可能是一个解决方案: 可在github.com/floscodes/golang-tools上获得
import (
"fmt"
"io/ioutil"
"os"
)
func CopyDir(src string, dest string) error {
if dest[:len(src)] == src {
return fmt.Errorf("Cannot copy a folder into the folder itself!")
}
f, err := os.Open(src)
if err != nil {
return err
}
file, err := f.Stat()
if err != nil {
return err
}
if !file.IsDir() {
return fmt.Errorf("Source " + file.Name() + " is not a directory!")
}
err = os.Mkdir(dest, 0755)
if err != nil {
return err
}
files, err := ioutil.ReadDir(src)
if err != nil {
return err
}
for _, f := range files {
if f.IsDir() {
err = CopyDir(src+"/"+f.Name(), dest+"/"+f.Name())
if err != nil {
return err
}
}
if !f.IsDir() {
content, err := ioutil.ReadFile(src + "/" + f.Name())
if err != nil {
return err
}
err = ioutil.WriteFile(dest+"/"+f.Name(), content, 0755)
if err != nil {
return err
}
}
}
return nil
}
你能告诉我们你的
CopyDir
功能是什么吗?那么我们也许可以帮助你。这应该在哪个系统上工作?您可以使用一个系统程序,例如cp
,它复制您的文件夹。您可以通过os/exec
包调用该程序。@apxp有由多个包组成的库;)请不要只发布链接,发布一点示例和描述。我实际上已经尝试过专门使用这个,这是有问题的,因为它没有保留目录树结构,它只是复制文件夹的内容并将所有内容转储到目标中。然后你最好尝试另一个答案建议的方法,要使用exec.command
@otiai10执行cp命令,@PASH I能够成功地使用版本v1.2.0
中的github.com/otiai10/copy
模块,您可以将Oleg解决方案的主要思想用于此包:。为了保存与Windows的兼容性,它不会执行os.Lchown()
或syscall.Stat\t
部分。如果出现错误,您应该执行延时退出。关闭()无
。而且该代码根本无法在Windows上编译。@rustyx感谢您的反馈,并与defer联系。上面有关于为什么它与windows不兼容的评论。docker copy github的最新链接如果relPath==“{return nil}
不能正常工作,因为每当info.IsDir为true时,它必须创建目录