rob
unread,Mar 11, 2021, 7:55:23 AM3/11/21Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to golang-nuts
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