1// Package cp offers simple file and directory copying for Go. 2package cp 3 4import ( 5 "errors" 6 "io" 7 "os" 8 "path/filepath" 9 "strings" 10) 11 12var errCopyFileWithDir = errors.New("dir argument to CopyFile") 13 14// CopyFile copies the file with path src to dst. The new file must not exist. 15// It is created with the same permissions as src. 16func CopyFile(dst, src string) error { 17 rf, err := os.Open(src) 18 if err != nil { 19 return err 20 } 21 defer rf.Close() 22 rstat, err := rf.Stat() 23 if err != nil { 24 return err 25 } 26 if rstat.IsDir() { 27 return errCopyFileWithDir 28 } 29 30 wf, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_EXCL, rstat.Mode()) 31 if err != nil { 32 return err 33 } 34 if _, err := io.Copy(wf, rf); err != nil { 35 wf.Close() 36 return err 37 } 38 return wf.Close() 39} 40 41// CopyAll copies the file or (recursively) the directory at src to dst. 42// Permissions are preserved. dst must not already exist. 43func CopyAll(dst, src string) error { 44 return filepath.Walk(src, makeWalkFn(dst, src)) 45} 46 47func makeWalkFn(dst, src string) filepath.WalkFunc { 48 return func(path string, info os.FileInfo, err error) error { 49 if err != nil { 50 return err 51 } 52 dstPath := filepath.Join(dst, strings.TrimPrefix(path, src)) 53 if info.IsDir() { 54 return os.Mkdir(dstPath, info.Mode()) 55 } 56 return CopyFile(dstPath, path) 57 } 58} 59