readdir.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // Copyright 2020 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 fs
  5. import (
  6. "errors"
  7. "sort"
  8. )
  9. // ReadDirFS is the interface implemented by a file system
  10. // that provides an optimized implementation of ReadDir.
  11. type ReadDirFS interface {
  12. FS
  13. // ReadDir reads the named directory
  14. // and returns a list of directory entries sorted by filename.
  15. ReadDir(name string) ([]DirEntry, error)
  16. }
  17. // ReadDir reads the named directory
  18. // and returns a list of directory entries sorted by filename.
  19. //
  20. // If fs implements ReadDirFS, ReadDir calls fs.ReadDir.
  21. // Otherwise ReadDir calls fs.Open and uses ReadDir and Close
  22. // on the returned file.
  23. func ReadDir(fsys FS, name string) ([]DirEntry, error) {
  24. if fsys, ok := fsys.(ReadDirFS); ok {
  25. return fsys.ReadDir(name)
  26. }
  27. file, err := fsys.Open(name)
  28. if err != nil {
  29. return nil, err
  30. }
  31. defer file.Close()
  32. dir, ok := file.(ReadDirFile)
  33. if !ok {
  34. return nil, &PathError{Op: "readdir", Path: name, Err: errors.New("not implemented")}
  35. }
  36. list, err := dir.ReadDir(-1)
  37. sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
  38. return list, err
  39. }
  40. // dirInfo is a DirEntry based on a FileInfo.
  41. type dirInfo struct {
  42. fileInfo FileInfo
  43. }
  44. func (di dirInfo) IsDir() bool {
  45. return di.fileInfo.IsDir()
  46. }
  47. func (di dirInfo) Type() FileMode {
  48. return di.fileInfo.Mode().Type()
  49. }
  50. func (di dirInfo) Info() (FileInfo, error) {
  51. return di.fileInfo, nil
  52. }
  53. func (di dirInfo) Name() string {
  54. return di.fileInfo.Name()
  55. }
  56. // FileInfoToDirEntry returns a DirEntry that returns information from info.
  57. // If info is nil, FileInfoToDirEntry returns nil.
  58. func FileInfoToDirEntry(info FileInfo) DirEntry {
  59. if info == nil {
  60. return nil
  61. }
  62. return dirInfo{fileInfo: info}
  63. }