| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- package godirwalk
- import (
- "os"
- "path/filepath"
- )
- // Dirent stores the name and file system mode type of discovered file system
- // entries.
- type Dirent struct {
- name string // base name of the file system entry.
- path string // path name of the file system entry.
- modeType os.FileMode // modeType is the type of file system entry.
- }
- // NewDirent returns a newly initialized Dirent structure, or an error. This
- // function does not follow symbolic links.
- //
- // This function is rarely used, as Dirent structures are provided by other
- // functions in this library that read and walk directories, but is provided,
- // however, for the occasion when a program needs to create a Dirent.
- func NewDirent(osPathname string) (*Dirent, error) {
- modeType, err := modeType(osPathname)
- if err != nil {
- return nil, err
- }
- return &Dirent{
- name: filepath.Base(osPathname),
- path: filepath.Dir(osPathname),
- modeType: modeType,
- }, nil
- }
- // IsDir returns true if and only if the Dirent represents a file system
- // directory. Note that on some operating systems, more than one file mode bit
- // may be set for a node. For instance, on Windows, a symbolic link that points
- // to a directory will have both the directory and the symbolic link bits set.
- func (de Dirent) IsDir() bool { return de.modeType&os.ModeDir != 0 }
- // IsDirOrSymlinkToDir returns true if and only if the Dirent represents a file
- // system directory, or a symbolic link to a directory. Note that if the Dirent
- // is not a directory but is a symbolic link, this method will resolve by
- // sending a request to the operating system to follow the symbolic link.
- func (de Dirent) IsDirOrSymlinkToDir() (bool, error) {
- if de.IsDir() {
- return true, nil
- }
- if !de.IsSymlink() {
- return false, nil
- }
- // Does this symlink point to a directory?
- info, err := os.Stat(filepath.Join(de.path, de.name))
- if err != nil {
- return false, err
- }
- return info.IsDir(), nil
- }
- // IsRegular returns true if and only if the Dirent represents a regular file.
- // That is, it ensures that no mode type bits are set.
- func (de Dirent) IsRegular() bool { return de.modeType&os.ModeType == 0 }
- // IsSymlink returns true if and only if the Dirent represents a file system
- // symbolic link. Note that on some operating systems, more than one file mode
- // bit may be set for a node. For instance, on Windows, a symbolic link that
- // points to a directory will have both the directory and the symbolic link bits
- // set.
- func (de Dirent) IsSymlink() bool { return de.modeType&os.ModeSymlink != 0 }
- // IsDevice returns true if and only if the Dirent represents a device file.
- func (de Dirent) IsDevice() bool { return de.modeType&os.ModeDevice != 0 }
- // ModeType returns the mode bits that specify the file system node type. We
- // could make our own enum-like data type for encoding the file type, but Go's
- // runtime already gives us architecture independent file modes, as discussed in
- // `os/types.go`:
- //
- // Go's runtime FileMode type has same definition on all systems, so that
- // information about files can be moved from one system to another portably.
- func (de Dirent) ModeType() os.FileMode { return de.modeType }
- // Name returns the base name of the file system entry.
- func (de Dirent) Name() string { return de.name }
- // reset releases memory held by entry err and name, and resets mode type to 0.
- func (de *Dirent) reset() {
- de.name = ""
- de.path = ""
- de.modeType = 0
- }
- // Dirents represents a slice of Dirent pointers, which are sortable by base
- // name. This type satisfies the `sort.Interface` interface.
- type Dirents []*Dirent
- // Len returns the count of Dirent structures in the slice.
- func (l Dirents) Len() int { return len(l) }
- // Less returns true if and only if the base name of the element specified by
- // the first index is lexicographically less than that of the second index.
- func (l Dirents) Less(i, j int) bool { return l[i].name < l[j].name }
- // Swap exchanges the two Dirent entries specified by the two provided indexes.
- func (l Dirents) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
|