github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/os/dir.go (about)

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