错误列出文件夹内容

huangapple go评论83阅读模式
英文:

Error listing folder contents

问题

使用Go 1.8.1,我正在尝试编写一个处理文件的程序。问题是,虽然filepath.Walk(...)可以正常工作,但我需要更灵活的解决方案。所以我转而使用ioutil.ReadDir(...),结果却遇到了一个令人惊讶的错误:“panic: runtime error: invalid memory address or nil pointer dereference”。我尝试了其他方法(filepath.Glob(...)file.Readdirnames(...)),它们都导致相同的错误。
真正令人困惑的是,filepath.Walk(...)使用了os.Lstat(...),但当我尝试直接使用os.Lstat(...)时...我得到了上面相同的错误。
我在更新的Ubuntu 16.04 LTS和更新的Fedora 25上都尝试过,结果没有任何区别。

我的Go技能非常薄弱(除了“hello world”之外,这是我第一个应用程序),所以任何帮助都将不胜感激。

以下是一些失败的代码:

func glob() {
    infos, err := filepath.Glob("*")
    if err != nil {
        for _, info := range infos {
            fmt.Println(info)
        }
    } else {
        log.Fatal(err.Error())
    }
}

func y() {
    file, err := os.Open(folder)
    println(file.Name())
    defer file.Close()
    infos, err := file.Readdirnames(0)
    //infos, err := ioutil.ReadDir(folder)
    if err != nil {
        for _, info := range infos {
            fmt.Println(info)
        }
    } else {
        log.Fatal(err.Error())
    }
}

func readDir() {
    infos, err := ioutil.ReadDir(folder)
    if err != nil {
        for _, info := range infos {
            fmt.Println(info)
        }
    } else {
        log.Fatal(err.Error())
    }
}

以下是有效的代码:

func walk() {
    err := filepath.Walk(folder, printWalk)
    if err != nil {
        log.Fatal(os.Stderr, "walk failed with error: %v\n", err)
    }
}

func printWalk(path string, info os.FileInfo, err error) error {
    if err != nil {
        return err
    }
    fmt.Println("path:", path, "FileInfo.Name:", info.Name())
    return nil
}
英文:

Using Go 1.8.1, I'm trying to write something that handles files. The trouble is, while filepath.Walk(...) works ok, I need something a bit more flexible. So I turn to ioutil.ReadDir(...), only to be greeted with a spectacular "panic: runtime error: invalid memory address or nil pointer dereference". I've tried alternatives (filepath.Glob(...), file.Readdirnames(...)), they all result in the same error.
What's really puzzling is filepath.Walk(...) uses os.Lstat(...), but when I try to use os.Lstat(...) directly... I get the same error above.
I've tried this on an updated Ubuntu 16.04 LTS and on an updated Fedora 25, it made no difference.

My Go-fu is really weak (this is my first application besides "hello world"), so any help is appreciated.

Here's some code that fails:

func glob() {
    infos, err := filepath.Glob("*")
    if err != nil {
	    for _, info := range infos {
		    fmt.Println(info)
	    }
    } else {
	    log.Fatal(err.Error())
    }
}

func y() {
    file, err := os.Open(folder)
    println(file.Name())
    defer file.Close()
    infos, err := file.Readdirnames(0)
    //infos, err := ioutil.ReadDir(folder)
    if err != nil {
	    for _, info := range infos {
		    fmt.Println(info)
	    }
    } else {
	    log.Fatal(err.Error())
    }
}

func readDir() {
    infos, err := ioutil.ReadDir(folder)
    if err != nil {
	    for _, info := range infos {
		    fmt.Println(info)
	    }
    } else {
	    log.Fatal(err.Error())
    }
}

and here's what works:

func walk() {
    err := filepath.Walk(folder, printWalk)
    if err != nil {
	    log.Fatal(os.Stderr, "walk failed with error: %v\n", err)
    }
}

func printWalk(path string, info os.FileInfo, err error) error {
    if err != nil {
	    return err
    }
    fmt.Println("path:", path, "FileInfo.Name:", info.Name())
    return nil
}

答案1

得分: 1

你的err检查对我来说有些反常。我本来期望的是这样的写法:

func readDir() {
    infos, err := ioutil.ReadDir(folder)
    if err != nil {
        log.Fatal(err)
    }
    for _, info := range infos {
        fmt.Println(info)
    }
}

一个更符合惯用写法的版本是将folder作为参数,并返回任何错误:

func readDir(folder string) error {
    infos, err := ioutil.ReadDir(folder)
    if err != nil {
        return err
    }
    for _, info := range infos {
        fmt.Println(info)
    }
    return nil
}
英文:

Your err check looks backwards to me. I would have expected:

func readDir() {
	infos, err := ioutil.ReadDir(folder)
	if err != nil {
		log.Fatal(err)
	}
	for _, info := range infos {
		fmt.Println(info)
	}
}

A more idiomatic version which has folder as a parameter and returns any error is:

func readDir(folder string) error {
	infos, err := ioutil.ReadDir(folder)
	if err != nil {
		return err
	}
	for _, info := range infos {
		fmt.Println(info)
	}
	return nil
}

答案2

得分: 0

你正在错误地检查错误。

if err != nil {  // 如果有错误(!)
    // 做一些事情(好像没有错误一样)
} else {
    log.Fatal(err.Error()) // 在这里发生了解引用,其中 err == nil。
}
英文:

You are checking the error wrongly.

if err != nil {  // if there is an error (!)
    // do something (as if there was no error)
} else {
    log.Fatal(err.Error()) // the dereference happens here, where err == nil.
}

huangapple
  • 本文由 发表于 2017年5月14日 23:48:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/43965899.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定