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.

Reply via email to