GOLANG:走目录树和进程文件 - err ='没有这样的文件或目录 [英] GOLANG: Walk Directory Tree and Process Files -- err = 'no such file or directory

查看:374
本文介绍了GOLANG:走目录树和进程文件 - err ='没有这样的文件或目录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个例程来遍历目录树,并为我找到的每个文件创建一个数字签名(salted-hash)。当测试它时,我得到了这个奇怪的行为 - 如果我给程序一个根目录路径在目录之上,程序可以遍历树并打印出文件名,但是如果我尝试打开文件来读取它的字节,我在例程找到的文件上得到错误信息no such file or directory - 不知道这里给出了什么。如何使Walk()例程查看文件,但ioutil.ReadFile()无法找到它?



示例代码:

  //以高于树的路径开始,例如$ HOME 
func doHashWalk(dirPath字符串){
err:=文件路径.Walk(dirPath,walkFn)
// Check err here
}

func walkFn(path string,fi os.FileInfo,err error)(e error){

if!fi.IsDir(){
//如果第一个字符是。,则跳过它作为隐藏文件

if strings.HasPrefix (fi.Name(),。){
return nil
}

//在文件中读取bytes - >获取绝对路径
fullPath,err:= filepath.Abs​​(fi.Name())
if err!= nil {
log.Printf(Abs Err:%s,err )
}

//总是失败,出现错误
字节,err:= ioutil.ReadFile(fullPath)//< - (fi.Name()also doesn如果错误!= nil {
log.Printf(Err:%s,Bytes:%d,err,len(bytes))
}


//创建盐渍散列
...
}
返回零
}


解决方案 c>尝试记录路径与的完整路径在 walkFn 中。

使用 filepath.Abs​​()没有给出你想要的结果:它解析了一个与当前工作目录相关的文件名,而不是原来的dirPath。



一个选项是将目标目录解析为绝对路径在 doHashWalk 中:


$ b

  func doHashWalk(dirPath string ){
fullPath,err:= filepath.Abs​​(dirPath)

if err!= nil {
log.Println(path error:,err)

返回
}

err = filepath.Walk(fullPath,walkFn)

//检查错误在这里
}

通过该更改, walkFn 回调将始终接收完全限定路径参数;无需再次调用 filepath.Abs​​()

  func walkFn (错误){
// ...

字节,错误:= ioutil.ReadFile(路径)

// ...
}

如果您的应用程序很重要每个文件相对于原始 dirPath root的路径,您可以通过闭包将该路径潜入 walkFn 回调:

  func doHashWalk(dirPath字符串)错误{

fullPath,err:= filepath.Abs dirPath)

if err!= nil {
return err
}

callback:= func(路径字符串,fi os.FileInfo,err错误)错误{
返回hashFile(fullPath,path,fi,err)
}

返回filepath.Walk(fullPath,回调)
}

func hashFile(根字符串,路径字符串,fi os.FileInfo,err错误)错误{
if fi.IsDir(){
return nil
}

rel,err:= filepath.Rel(root,path)

if err!= nil {
return err
}

log.Println(hash rel:,rel,abs:,path)

return nil
}


I'm writing a routine to walk a directory tree and create a digital signature (salted-hash) for each file I find. When testing it I get this weird behavior - if I give the program a root path "above" the directory, the program can walk the tree and print out the file names, but if I try and open the file to read it's bytes, I get the error message "no such file or directory" on the file that the routines found - not sure what gives here. How can the Walk() routine "see" the file, but ioutil.ReadFile() not be able to find it?

Sample Code:

// start with path higher up the tree, say $HOME
func doHashWalk(dirPath string) {
    err := filepath.Walk(dirPath, walkFn)
    // Check err here
}

func walkFn(path string, fi os.FileInfo, err error) (e error) {

    if !fi.IsDir() {
        // if the first character is a ".", then skip it as it's a hidden file

        if strings.HasPrefix(fi.Name(), ".") {
            return nil
        }

        // read in the file bytes -> get the absolute path
        fullPath, err := filepath.Abs(fi.Name())
        if err != nil {
            log.Printf("Abs Err: %s", err)
        }

        // THIS ALWAYS FAILED WITH ERROR
        bytes, err := ioutil.ReadFile(fullPath) // <-- (fi.Name() also doesn't work)
        if err != nil {
            log.Printf("Err: %s, Bytes: %d", err, len(bytes))     
        }

        // create the salted hash
        ...
    }
    return nil
}

解决方案

Try logging the values of path vs. fullPath inside of walkFn.

Using filepath.Abs() inside of walkFn does not give the result you want: it's resolving a filename relative to the current working directory, instead of the original dirPath.

One option is to resolve the target directory to an absolute path up-front in doHashWalk:

func doHashWalk(dirPath string) {
    fullPath, err := filepath.Abs(dirPath)

    if err != nil {
        log.Println("path error:", err)

        return
    }

    err = filepath.Walk(fullPath, walkFn)

    // check err here
}

With that change, the walkFn callback will always receive a fully-qualified path argument; no need to call filepath.Abs() again:

func walkFn(path string, fi os.FileInfo, err error) (e error) {
    // ...

    bytes, err := ioutil.ReadFile(path)

    // ...
}

If it's important for your application to see the path of each file relative to the original dirPath root, you can sneak that path into the walkFn callback via a closure:

func doHashWalk(dirPath string) error {

    fullPath, err := filepath.Abs(dirPath)

    if err != nil {
        return err
    }

    callback := func(path string, fi os.FileInfo, err error) error {
        return hashFile(fullPath, path, fi, err)
    }

    return filepath.Walk(fullPath, callback)
}

func hashFile(root string, path string, fi os.FileInfo, err error) error {
    if fi.IsDir() {
        return nil
    }

    rel, err := filepath.Rel(root, path)

    if err != nil {
        return err
    }

    log.Println("hash rel:", rel, "abs:", path)

    return nil
}

这篇关于GOLANG:走目录树和进程文件 - err ='没有这样的文件或目录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆