Ultima attività 1 month ago

Go 语言文件和文件夹复制 转:https://gist.github.com/r0l1/92462b38df26839a3ca324697c8cba04

jetsung ha revisionato questo gist 9 months ago. Vai alla revisione

1 file changed, 124 insertions

copy.go(file creato)

@@ -0,0 +1,124 @@
1 + /* MIT License
2 + *
3 + * Copyright (c) 2017 Roland Singer [[email protected]]
4 + *
5 + * Permission is hereby granted, free of charge, to any person obtaining a copy
6 + * of this software and associated documentation files (the "Software"), to deal
7 + * in the Software without restriction, including without limitation the rights
8 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 + * copies of the Software, and to permit persons to whom the Software is
10 + * furnished to do so, subject to the following conditions:
11 + *
12 + * The above copyright notice and this permission notice shall be included in all
13 + * copies or substantial portions of the Software.
14 + *
15 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 + * SOFTWARE.
22 + */
23 +
24 + // CopyFile copies the contents of the file named src to the file named
25 + // by dst. The file will be created if it does not already exist. If the
26 + // destination file exists, all it's contents will be replaced by the contents
27 + // of the source file. The file mode will be copied from the source and
28 + // the copied data is synced/flushed to stable storage.
29 + func CopyFile(src, dst string) (err error) {
30 + in, err := os.Open(src)
31 + if err != nil {
32 + return
33 + }
34 + defer in.Close()
35 +
36 + out, err := os.Create(dst)
37 + if err != nil {
38 + return
39 + }
40 + defer func() {
41 + if e := out.Close(); e != nil {
42 + err = e
43 + }
44 + }()
45 +
46 + _, err = io.Copy(out, in)
47 + if err != nil {
48 + return
49 + }
50 +
51 + err = out.Sync()
52 + if err != nil {
53 + return
54 + }
55 +
56 + si, err := os.Stat(src)
57 + if err != nil {
58 + return
59 + }
60 + err = os.Chmod(dst, si.Mode())
61 + if err != nil {
62 + return
63 + }
64 +
65 + return
66 + }
67 +
68 + // CopyDir recursively copies a directory tree, attempting to preserve permissions.
69 + // Source directory must exist, destination directory must *not* exist.
70 + // Symlinks are ignored and skipped.
71 + func CopyDir(src string, dst string) (err error) {
72 + src = filepath.Clean(src)
73 + dst = filepath.Clean(dst)
74 +
75 + si, err := os.Stat(src)
76 + if err != nil {
77 + return err
78 + }
79 + if !si.IsDir() {
80 + return fmt.Errorf("source is not a directory")
81 + }
82 +
83 + _, err = os.Stat(dst)
84 + if err != nil && !os.IsNotExist(err) {
85 + return
86 + }
87 + if err == nil {
88 + return fmt.Errorf("destination already exists")
89 + }
90 +
91 + err = os.MkdirAll(dst, si.Mode())
92 + if err != nil {
93 + return
94 + }
95 +
96 + entries, err := ioutil.ReadDir(src)
97 + if err != nil {
98 + return
99 + }
100 +
101 + for _, entry := range entries {
102 + srcPath := filepath.Join(src, entry.Name())
103 + dstPath := filepath.Join(dst, entry.Name())
104 +
105 + if entry.IsDir() {
106 + err = CopyDir(srcPath, dstPath)
107 + if err != nil {
108 + return
109 + }
110 + } else {
111 + // Skip symlinks.
112 + if entry.Mode()&os.ModeSymlink != 0 {
113 + continue
114 + }
115 +
116 + err = CopyFile(srcPath, dstPath)
117 + if err != nil {
118 + return
119 + }
120 + }
121 + }
122 +
123 + return
124 + }
Più nuovi Più vecchi