dir_handle.go 2.9 KB

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