Hi, I'm not entirely sure what is happening (it's hard to see without getting more information about the actual file tree and what files you get errors for) and what OS you are running on. But one observation is that you glob for *.txt and then call `ReadDir` on the result - that doesn't make much sense to me, the first would suggest the filenames are regular files, but calling `ReadDir` does not make sense unless you expect it to be a directory. I would expect that to return a wrapper around syscall.ENOTDIR, but again, depending on the OS there might be idiosyncrasies I'm not expecting. But this would definitely explain why LStat works, while ReadDir doesn't - the file exists, it just isn't a directory.
On Thu, Mar 11, 2021 at 1:55 PM rob <drrob...@fastmail.com> wrote: > I've been writing some code to learn about the library changes in Go 1.16. > > The following code uses filepath.Glob to get a slice of matching > filenames, then uses os.ReadDir to get more information about these > files. I found that os.ReadDir reports a file not found error for the > filenames returned by filepath.Glob. I do not understand why, as when I > use os.Lstat there are no errors. This code is extracted and simplified > from a longer program I wrote. > > This code has been compiled w/ go1.16.1 and I'm getting the same error > messages. > > I do not understand why. I would have expected that os.ReadDir can find > the filename just as os.Lstat does. > > --rob solomon > > > // rddirpblm to isolate the problem w/ going from filepath.Glob to > os.ReadDir on Win10. > > package main > > import ( > "fmt" > "os" > "path/filepath" > "runtime" > "strconv" > ) > > const LastAltered = "11 Mar 2021" > > /* > Revision History > ---------------- > 11 Mar 21 -- Isolating Glob -> ReadDir issue. Go 1.16 is deprecating > ioutil functions. > */ > > func main() { > var err error > > fmt.Print("rddirpblm LastAltered ", LastAltered, ", compiled using > ", runtime.Version(), ".") > fmt.Println() > > direntries := make([]os.DirEntry, 0, 500) > > sepstring := string(filepath.Separator) > HomeDirStr, e := os.UserHomeDir() // HomeDir code used for > processing ~ symbol meaning home directory. > if e != nil { > fmt.Fprintln(os.Stderr, e) > HomeDirStr = "" > } > HomeDirStr = HomeDirStr + sepstring > fmt.Println(" HomeDirStr is", HomeDirStr) > > globfor := "*.txt" > > filenamesStringSlice, err := filepath.Glob(globfor) > if err != nil { > fmt.Fprintln(os.Stderr, err, " Exiting.") > os.Exit(1) > } > > for i := 0; i < 20; i++ { > fn := filenamesStringSlice[i] > direntry, err := os.ReadDir(fn) > if err != nil { > fmt.Fprintln(os.Stderr, "fn =", fn, err) > fmt.Fprintln(os.Stderr, "Will try os.Lstat") > fi, er := os.Lstat(fn) > if er != nil { > fmt.Fprintln(os.Stderr, err) > } > fmt.Println("From os.Lstat: Name =", fi.Name(), ", Size =", > fi.Size(), ", IsDir =", fi.IsDir()) > fmt.Println() > continue > } > if len(direntry) > 1 { > fmt.Fprintln(os.Stderr, " expecting only 1 direntry, but > len(direntry) is", len(direntry), ". Don't know what this means yet.") > } > direntries = append(direntries, direntry[0]) > } > > for _, d := range direntries { > f, err := d.Info() > if err != nil { > fmt.Fprintln(os.Stderr, err, ". No idea why this caused an > error.") > } > > sizestr := strconv.FormatInt(f.Size(), 10) > if f.Size() > 100000 { > sizestr = AddCommas(sizestr) > } > fmt.Printf("%17s %s %s\n", sizestr, sizestr, d.Name()) > } // end for range direntries > } // end main > > //-------------------------------------------------------------------- > InsertByteSlice > func InsertIntoByteSlice(slice, insertion []byte, index int) []byte { > return append(slice[:index], append(insertion, slice[index:]...)...) > } // InsertIntoByteSlice > > //---------------------------------------------------------------------- > AddCommas > func AddCommas(instr string) string { > //var Comma []byte = []byte{','} Getting error that type can be > omitted > Comma := []byte{','} > > BS := make([]byte, 0, 15) > BS = append(BS, instr...) > > i := len(BS) > > for NumberOfCommas := i / 3; (NumberOfCommas > 0) && (i > 3); > NumberOfCommas-- { > i -= 3 > BS = InsertIntoByteSlice(BS, Comma, i) > } > return string(BS) > } // AddCommas > > // ------------------------------- MyReadDir > ----------------------------------- > func MyReadDir(dir string) []os.DirEntry { > > dirname, err := os.Open(dir) > if err != nil { > fmt.Fprintln(os.Stderr, err) > return nil > } > defer dirname.Close() > > names, err := dirname.Readdirnames(0) // zero means read all names > into the returned []string > if err != nil { > fmt.Fprintln(os.Stderr, err) > return nil > } > > direntries := make([]os.DirEntry, 0, len(names)) > for _, name := range names { > d, err := os.ReadDir(name) > if err != nil { > fmt.Fprintln(os.Stderr, " Error from os.ReadDir. ", err) > continue > } > if len(d) > 1 { > fmt.Fprintln(os.Stderr, " expected len(d) == 1, but it's", > len(d), ", which I don't yet understand.") > } > direntries = append(direntries, d[0]) > } > return direntries > } // MyReadDir > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/f8e57e32-1f61-abe5-77fa-b48586c4524a%40fastmail.com > . > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAEkBMfGdR4LToOop3DY6QBdDYqkULF5-eNN2V%3DRLs4tLW5%2BhxQ%40mail.gmail.com.