cp.go 1.3 KB

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