github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/vfs/dir_handle.go (about) 1 package vfs 2 3 import ( 4 "io" 5 "os" 6 ) 7 8 // DirHandle represents an open directory 9 type DirHandle struct { 10 baseHandle 11 d *Dir 12 fis []os.FileInfo // where Readdir got to 13 } 14 15 // newDirHandle opens a directory for read 16 func newDirHandle(d *Dir) *DirHandle { 17 return &DirHandle{ 18 d: d, 19 } 20 } 21 22 // String converts it to printable 23 func (fh *DirHandle) String() string { 24 if fh == nil { 25 return "<nil *DirHandle>" 26 } 27 if fh.d == nil { 28 return "<nil *DirHandle.d>" 29 } 30 return fh.d.String() + " (r)" 31 } 32 33 // Stat returns info about the current directory 34 func (fh *DirHandle) Stat() (fi os.FileInfo, err error) { 35 return fh.d, nil 36 } 37 38 // Node returns the Node assocuated with this - satisfies Noder interface 39 func (fh *DirHandle) Node() Node { 40 return fh.d 41 } 42 43 // Readdir reads the contents of the directory associated with file and returns 44 // a slice of up to n FileInfo values, as would be returned by Lstat, in 45 // directory order. Subsequent calls on the same file will yield further 46 // FileInfos. 47 // 48 // If n > 0, Readdir returns at most n FileInfo structures. In this case, if 49 // Readdir returns an empty slice, it will return a non-nil error explaining 50 // why. At the end of a directory, the error is io.EOF. 51 // 52 // If n <= 0, Readdir returns all the FileInfo from the directory in a single 53 // slice. In this case, if Readdir succeeds (reads all the way to the end of 54 // the directory), it returns the slice and a nil error. If it encounters an 55 // error before the end of the directory, Readdir returns the FileInfo read 56 // until that point and a non-nil error. 57 func (fh *DirHandle) Readdir(n int) (fis []os.FileInfo, err error) { 58 if fh.fis == nil { 59 nodes, err := fh.d.ReadDirAll() 60 if err != nil { 61 return nil, err 62 } 63 fh.fis = []os.FileInfo{} 64 for _, node := range nodes { 65 fh.fis = append(fh.fis, node) 66 } 67 } 68 nn := len(fh.fis) 69 if n > 0 { 70 if nn == 0 { 71 return nil, io.EOF 72 } 73 if nn > n { 74 nn = n 75 } 76 } 77 fis, fh.fis = fh.fis[:nn], fh.fis[nn:] 78 return fis, nil 79 } 80 81 // Readdirnames reads and returns a slice of names from the directory f. 82 // 83 // If n > 0, Readdirnames returns at most n names. In this case, if 84 // Readdirnames returns an empty slice, it will return a non-nil error 85 // explaining why. At the end of a directory, the error is io.EOF. 86 // 87 // If n <= 0, Readdirnames returns all the names from the directory in a single 88 // slice. In this case, if Readdirnames succeeds (reads all the way to the end 89 // of the directory), it returns the slice and a nil error. If it encounters an 90 // error before the end of the directory, Readdirnames returns the names read 91 // until that point and a non-nil error. 92 func (fh *DirHandle) Readdirnames(n int) (names []string, err error) { 93 nodes, err := fh.Readdir(n) 94 if err != nil { 95 return nil, err 96 } 97 for _, node := range nodes { 98 names = append(names, node.Name()) 99 } 100 return names, nil 101 } 102 103 // Close closes the handle 104 func (fh *DirHandle) Close() (err error) { 105 fh.fis = nil 106 return nil 107 }