1 // Copyright 2009 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" 9 "syscall" 10 ) 11 12 func (file *File) readdir(n int) (fi []FileInfo, err error) { 13 if file == nil { 14 return nil, syscall.EINVAL 15 } 16 if !file.isdir() { 17 return nil, &PathError{"Readdir", file.name, syscall.ENOTDIR} 18 } 19 if !file.dirinfo.isempty && file.fd == syscall.InvalidHandle { 20 return nil, syscall.EINVAL 21 } 22 wantAll := n <= 0 23 size := n 24 if wantAll { 25 n = -1 26 size = 100 27 } 28 fi = make([]FileInfo, 0, size) // Empty with room to grow. 29 d := &file.dirinfo.data 30 for n != 0 && !file.dirinfo.isempty { 31 if file.dirinfo.needdata { 32 e := syscall.FindNextFile(file.fd, d) 33 if e != nil { 34 if e == syscall.ERROR_NO_MORE_FILES { 35 break 36 } else { 37 err = &PathError{"FindNextFile", file.name, e} 38 if !wantAll { 39 fi = nil 40 } 41 return 42 } 43 } 44 } 45 file.dirinfo.needdata = true 46 name := syscall.UTF16ToString(d.FileName[0:]) 47 if name == "." || name == ".." { // Useless names 48 continue 49 } 50 f := &fileStat{ 51 name: name, 52 sys: syscall.Win32FileAttributeData{ 53 FileAttributes: d.FileAttributes, 54 CreationTime: d.CreationTime, 55 LastAccessTime: d.LastAccessTime, 56 LastWriteTime: d.LastWriteTime, 57 FileSizeHigh: d.FileSizeHigh, 58 FileSizeLow: d.FileSizeLow, 59 }, 60 path: file.dirinfo.path + `\` + name, 61 } 62 n-- 63 fi = append(fi, f) 64 } 65 if !wantAll && len(fi) == 0 { 66 return fi, io.EOF 67 } 68 return fi, nil 69 } 70 71 func (file *File) readdirnames(n int) (names []string, err error) { 72 fis, err := file.Readdir(n) 73 names = make([]string, len(fis)) 74 for i, fi := range fis { 75 names[i] = fi.Name() 76 } 77 return names, err 78 } 79