Source file src/io/fs/readdir.go

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

View as plain text