From 8cfdc8f27fa4046664788f3e4ac42ecfcd2f5126 Mon Sep 17 00:00:00 2001 From: skiy Date: Mon, 8 Jul 2019 01:26:00 +0800 Subject: [PATCH] file and folder copy --- g/os/gfile/gfile.go | 104 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/g/os/gfile/gfile.go b/g/os/gfile/gfile.go index 81db327e2..931f3d9f1 100644 --- a/g/os/gfile/gfile.go +++ b/g/os/gfile/gfile.go @@ -16,6 +16,7 @@ import ( "github.com/gogf/gf/g/text/gstr" "github.com/gogf/gf/g/util/gconv" "io" + "io/ioutil" "os" "os/exec" "os/user" @@ -450,3 +451,106 @@ func MainPkgPath() string { func TempDir() string { return os.TempDir() } + +// https://gist.github.com/r0l1/92462b38df26839a3ca324697c8cba04 +// CopyFile copies the contents of the file named src to the file named +// by dst. The file will be created if it does not already exist. If the +// destination file exists, all it's contents will be replaced by the contents +// of the source file. The file mode will be copied from the source and +// the copied data is synced/flushed to stable storage. +func CopyFile(src, dst string) (err error) { + in, err := os.Open(src) + if err != nil { + return + } + defer in.Close() + + out, err := os.Create(dst) + if err != nil { + return + } + defer func() { + if e := out.Close(); e != nil { + err = e + } + }() + + _, err = io.Copy(out, in) + if err != nil { + return + } + + err = out.Sync() + if err != nil { + return + } + + si, err := os.Stat(src) + if err != nil { + return + } + err = os.Chmod(dst, si.Mode()) + if err != nil { + return + } + + return +} + +// CopyDir recursively copies a directory tree, attempting to preserve permissions. +// Source directory must exist, destination directory must *not* exist. +// Symlinks are ignored and skipped. +func CopyDir(src string, dst string) (err error) { + src = filepath.Clean(src) + dst = filepath.Clean(dst) + + si, err := os.Stat(src) + if err != nil { + return err + } + if !si.IsDir() { + return fmt.Errorf("source is not a directory") + } + + _, err = os.Stat(dst) + if err != nil && !os.IsNotExist(err) { + return + } + if err == nil { + return fmt.Errorf("destination already exists") + } + + err = os.MkdirAll(dst, si.Mode()) + if err != nil { + return + } + + entries, err := ioutil.ReadDir(src) + if err != nil { + return + } + + 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 + } + } else { + // Skip symlinks. + if entry.Mode()&os.ModeSymlink != 0 { + continue + } + + err = CopyFile(srcPath, dstPath) + if err != nil { + return + } + } + } + + return +} \ No newline at end of file