dir.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // Copyright 2016 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package os
  5. import (
  6. "io/fs"
  7. "sort"
  8. )
  9. type readdirMode int
  10. const (
  11. readdirName readdirMode = iota
  12. readdirDirEntry
  13. readdirFileInfo
  14. )
  15. // Readdir reads the contents of the directory associated with file and
  16. // returns a slice of up to n FileInfo values, as would be returned
  17. // by Lstat, in directory order. Subsequent calls on the same file will yield
  18. // further FileInfos.
  19. //
  20. // If n > 0, Readdir returns at most n FileInfo structures. In this case, if
  21. // Readdir returns an empty slice, it will return a non-nil error
  22. // explaining why. At the end of a directory, the error is io.EOF.
  23. //
  24. // If n <= 0, Readdir returns all the FileInfo from the directory in
  25. // a single slice. In this case, if Readdir succeeds (reads all
  26. // the way to the end of the directory), it returns the slice and a
  27. // nil error. If it encounters an error before the end of the
  28. // directory, Readdir returns the FileInfo read until that point
  29. // and a non-nil error.
  30. //
  31. // Most clients are better served by the more efficient ReadDir method.
  32. func (f *File) Readdir(n int) ([]FileInfo, error) {
  33. if f == nil {
  34. return nil, ErrInvalid
  35. }
  36. _, _, infos, err := f.readdir(n, readdirFileInfo)
  37. if infos == nil {
  38. // Readdir has historically always returned a non-nil empty slice, never nil,
  39. // even on error (except misuse with nil receiver above).
  40. // Keep it that way to avoid breaking overly sensitive callers.
  41. infos = []FileInfo{}
  42. }
  43. return infos, err
  44. }
  45. // Readdirnames reads the contents of the directory associated with file
  46. // and returns a slice of up to n names of files in the directory,
  47. // in directory order. Subsequent calls on the same file will yield
  48. // further names.
  49. //
  50. // If n > 0, Readdirnames returns at most n names. In this case, if
  51. // Readdirnames returns an empty slice, it will return a non-nil error
  52. // explaining why. At the end of a directory, the error is io.EOF.
  53. //
  54. // If n <= 0, Readdirnames returns all the names from the directory in
  55. // a single slice. In this case, if Readdirnames succeeds (reads all
  56. // the way to the end of the directory), it returns the slice and a
  57. // nil error. If it encounters an error before the end of the
  58. // directory, Readdirnames returns the names read until that point and
  59. // a non-nil error.
  60. func (f *File) Readdirnames(n int) (names []string, err error) {
  61. if f == nil {
  62. return nil, ErrInvalid
  63. }
  64. names, _, _, err = f.readdir(n, readdirName)
  65. if names == nil {
  66. // Readdirnames has historically always returned a non-nil empty slice, never nil,
  67. // even on error (except misuse with nil receiver above).
  68. // Keep it that way to avoid breaking overly sensitive callers.
  69. names = []string{}
  70. }
  71. return names, err
  72. }
  73. // A DirEntry is an entry read from a directory
  74. // (using the ReadDir function or a File's ReadDir method).
  75. type DirEntry = fs.DirEntry
  76. // ReadDir reads the contents of the directory associated with the file f
  77. // and returns a slice of DirEntry values in directory order.
  78. // Subsequent calls on the same file will yield later DirEntry records in the directory.
  79. //
  80. // If n > 0, ReadDir returns at most n DirEntry records.
  81. // In this case, if ReadDir returns an empty slice, it will return an error explaining why.
  82. // At the end of a directory, the error is io.EOF.
  83. //
  84. // If n <= 0, ReadDir returns all the DirEntry records remaining in the directory.
  85. // When it succeeds, it returns a nil error (not io.EOF).
  86. func (f *File) ReadDir(n int) ([]DirEntry, error) {
  87. if f == nil {
  88. return nil, ErrInvalid
  89. }
  90. _, dirents, _, err := f.readdir(n, readdirDirEntry)
  91. if dirents == nil {
  92. // Match Readdir and Readdirnames: don't return nil slices.
  93. dirents = []DirEntry{}
  94. }
  95. return dirents, err
  96. }
  97. // testingForceReadDirLstat forces ReadDir to call Lstat, for testing that code path.
  98. // This can be difficult to provoke on some Unix systems otherwise.
  99. var testingForceReadDirLstat bool
  100. // ReadDir reads the named directory,
  101. // returning all its directory entries sorted by filename.
  102. // If an error occurs reading the directory,
  103. // ReadDir returns the entries it was able to read before the error,
  104. // along with the error.
  105. func ReadDir(name string) ([]DirEntry, error) {
  106. f, err := Open(name)
  107. if err != nil {
  108. return nil, err
  109. }
  110. defer f.Close()
  111. dirs, err := f.ReadDir(-1)
  112. sort.Slice(dirs, func(i, j int) bool { return dirs[i].Name() < dirs[j].Name() })
  113. return dirs, err
  114. }