duanruanxian5028 2018-08-10 04:59
浏览 327
已采纳

在go中复制文件夹

Is there an easy way to copy a directory in go? I have the following function:

err = CopyDir("sourceFolder","destinationFolder")

Nothing so far has worked, including libraries such as github.com/cf-guardian/guardian/kernel/fileutils

One important thing to note is that I need to preserve directory structure, including the sourceFolder itself, not simply copy all contents of the folder.

  • 写回答

3条回答 默认 最新

  • dsg7513 2019-05-26 13:57
    关注

    I believe that docker implementation can be considered as complete solution for handling edge cases: https://github.com/moby/moby/blob/8e610b2b55bfd1bfa9436ab110d311f5e8a74dcb/daemon/graphdriver/copy/copy.go

    There are following good things:

    • unsupported file type rise error
    • preserving permissions and ownership
    • preserving extended attributes
    • preserving timestamp

    but because of a lot of imports your tiny application becomes huge.

    I've tried to combine several solutions but use stdlib only:

    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)
        defer out.Close()
        if err != nil {
            return err
        }
    
        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)
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 TLS1.2协议通信解密
  • ¥40 图书信息管理系统程序编写
  • ¥20 Qcustomplot缩小曲线形状问题
  • ¥15 企业资源规划ERP沙盘模拟
  • ¥15 树莓派控制机械臂传输命令报错,显示摄像头不存在
  • ¥15 前端echarts坐标轴问题
  • ¥15 ad5933的I2C
  • ¥15 请问RTX4060的笔记本电脑可以训练yolov5模型吗?
  • ¥15 数学建模求思路及代码
  • ¥50 silvaco GaN HEMT有栅极场板的击穿电压仿真问题