From 8cfdc8f27fa4046664788f3e4ac42ecfcd2f5126 Mon Sep 17 00:00:00 2001 From: skiy Date: Mon, 8 Jul 2019 01:26:00 +0800 Subject: [PATCH 1/2] 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 From 7c4431ceebe788c4f95aa11fd1301fd997177d0f Mon Sep 17 00:00:00 2001 From: skiy Date: Mon, 8 Jul 2019 11:37:02 +0800 Subject: [PATCH 2/2] add copyfile & copydir test --- g/os/gfile/gfile.go | 11 +++--- g/os/gfile/gfile_z_test.go | 73 ++++++++++++++++++++++++++++++++++++-- go.mod | 2 ++ 3 files changed, 79 insertions(+), 7 deletions(-) diff --git a/g/os/gfile/gfile.go b/g/os/gfile/gfile.go index 931f3d9f1..22cda24e2 100644 --- a/g/os/gfile/gfile.go +++ b/g/os/gfile/gfile.go @@ -11,10 +11,6 @@ import ( "bytes" "errors" "fmt" - "github.com/gogf/gf/g/container/gtype" - "github.com/gogf/gf/g/text/gregex" - "github.com/gogf/gf/g/text/gstr" - "github.com/gogf/gf/g/util/gconv" "io" "io/ioutil" "os" @@ -25,6 +21,11 @@ import ( "sort" "strings" "time" + + "github.com/gogf/gf/g/container/gtype" + "github.com/gogf/gf/g/text/gregex" + "github.com/gogf/gf/g/text/gstr" + "github.com/gogf/gf/g/util/gconv" ) const ( @@ -553,4 +554,4 @@ func CopyDir(src string, dst string) (err error) { } return -} \ No newline at end of file +} diff --git a/g/os/gfile/gfile_z_test.go b/g/os/gfile/gfile_z_test.go index b7d438434..44b8008ed 100644 --- a/g/os/gfile/gfile_z_test.go +++ b/g/os/gfile/gfile_z_test.go @@ -1,12 +1,13 @@ package gfile_test import ( - "github.com/gogf/gf/g/os/gfile" - "github.com/gogf/gf/g/test/gtest" "os" "path/filepath" "strings" "testing" + + "github.com/gogf/gf/g/os/gfile" + "github.com/gogf/gf/g/test/gtest" ) func TestIsDir(t *testing.T) { @@ -677,3 +678,71 @@ func TestMainPkgPath(t *testing.T) { gtest.Assert(reads, "") }) } + +func TestCopyFile(t *testing.T) { + gtest.Case(t, func() { + var ( + paths string = "/testfile_copyfile1.txt" + topath string = "/testfile_copyfile2.txt" + ) + + createTestFile(paths, "") + defer delTestFiles(paths) + + gtest.Assert(gfile.CopyFile(testpath()+paths, testpath()+topath), nil) + defer delTestFiles(topath) + + gtest.Assert(gfile.IsFile(testpath()+topath), true) + gtest.AssertNE(gfile.CopyFile("", ""), nil) + }) +} + +func TestCopyDir(t *testing.T) { + gtest.Case(t, func() { + var ( + dirpath1 string = "/testcopydir1" + dirpath2 string = "/testcopydir2" + ) + + havelist1 := []string{ + "t1.txt", + "t2.txt", + } + + createDir(dirpath1) + for _, v := range havelist1 { + createTestFile(dirpath1+"/"+v, "") + } + defer delTestFiles(dirpath1) + + yfolder := testpath() + dirpath1 + tofolder := testpath() + dirpath2 + + if gfile.IsDir(tofolder) { + gtest.Assert(gfile.Remove(tofolder), nil) + gtest.Assert(gfile.Remove(""), nil) + } + + gtest.Assert(gfile.CopyDir(yfolder, tofolder), nil) + defer delTestFiles(tofolder) + + // 检查复制后的旧文件夹是否真实存在 + gtest.Assert(gfile.IsDir(yfolder), true) + + // 检查复制后的旧文件夹中的文件是否真实存在 + for _, v := range havelist1 { + gtest.Assert(gfile.IsFile(yfolder+"/"+v), true) + } + + // 检查复制后的新文件夹是否真实存在 + gtest.Assert(gfile.IsDir(tofolder), true) + + // 检查复制后的新文件夹中的文件是否真实存在 + for _, v := range havelist1 { + gtest.Assert(gfile.IsFile(tofolder+"/"+v), true) + } + + gtest.Assert(gfile.Remove(tofolder), nil) + gtest.Assert(gfile.Remove(""), nil) + }) +} diff --git a/go.mod b/go.mod index ef37cb8d6..081d99cd0 100644 --- a/go.mod +++ b/go.mod @@ -1 +1,3 @@ module github.com/gogf/gf + +go 1.12