dirent.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package godirwalk
  2. import (
  3. "os"
  4. "path/filepath"
  5. "github.com/pkg/errors"
  6. )
  7. // Dirent stores the name and file system mode type of discovered file system
  8. // entries.
  9. type Dirent struct {
  10. name string
  11. modeType os.FileMode
  12. }
  13. // NewDirent returns a newly initialized Dirent structure, or an error. This
  14. // function does not follow symbolic links.
  15. //
  16. // This function is rarely used, as Dirent structures are provided by other
  17. // functions in this library that read and walk directories.
  18. func NewDirent(osPathname string) (*Dirent, error) {
  19. fi, err := os.Lstat(osPathname)
  20. if err != nil {
  21. return nil, errors.Wrap(err, "cannot lstat")
  22. }
  23. return &Dirent{
  24. name: filepath.Base(osPathname),
  25. modeType: fi.Mode() & os.ModeType,
  26. }, nil
  27. }
  28. // Name returns the basename of the file system entry.
  29. func (de Dirent) Name() string { return de.name }
  30. // ModeType returns the mode bits that specify the file system node type. We
  31. // could make our own enum-like data type for encoding the file type, but Go's
  32. // runtime already gives us architecture independent file modes, as discussed in
  33. // `os/types.go`:
  34. //
  35. // Go's runtime FileMode type has same definition on all systems, so that
  36. // information about files can be moved from one system to another portably.
  37. func (de Dirent) ModeType() os.FileMode { return de.modeType }
  38. // IsDir returns true if and only if the Dirent represents a file system
  39. // directory. Note that on some operating systems, more than one file mode bit
  40. // may be set for a node. For instance, on Windows, a symbolic link that points
  41. // to a directory will have both the directory and the symbolic link bits set.
  42. func (de Dirent) IsDir() bool { return de.modeType&os.ModeDir != 0 }
  43. // IsRegular returns true if and only if the Dirent represents a regular
  44. // file. That is, it ensures that no mode type bits are set.
  45. func (de Dirent) IsRegular() bool { return de.modeType&os.ModeType == 0 }
  46. // IsSymlink returns true if and only if the Dirent represents a file system
  47. // symbolic link. Note that on some operating systems, more than one file mode
  48. // bit may be set for a node. For instance, on Windows, a symbolic link that
  49. // points to a directory will have both the directory and the symbolic link bits
  50. // set.
  51. func (de Dirent) IsSymlink() bool { return de.modeType&os.ModeSymlink != 0 }
  52. // Dirents represents a slice of Dirent pointers, which are sortable by
  53. // name. This type satisfies the `sort.Interface` interface.
  54. type Dirents []*Dirent
  55. // Len returns the count of Dirent structures in the slice.
  56. func (l Dirents) Len() int { return len(l) }
  57. // Less returns true if and only if the Name of the element specified by the
  58. // first index is lexicographically less than that of the second index.
  59. func (l Dirents) Less(i, j int) bool { return l[i].name < l[j].name }
  60. // Swap exchanges the two Dirent entries specified by the two provided indexes.
  61. func (l Dirents) Swap(i, j int) { l[i], l[j] = l[j], l[i] }