GOLANG:走目录树和进程文件 - err ='没有这样的文件或目录 [英] GOLANG: Walk Directory Tree and Process Files -- err = 'no such file or directory
问题描述
我正在编写一个例程来遍历目录树,并为我找到的每个文件创建一个数字签名(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))
}
//创建盐渍散列
...
}
返回零
}
路径与的完整路径在 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屋!