使用文件路径在 Go 中搜索文件

Search for file in Go using filepath

我正在尝试使用 Go 在目录中查找文件。我正在使用文件路径包中的 Walk 函数。在 findFile 函数中,我正在获取文件并将其分配给正在传递的文件的指针。但这似乎不起作用,调用 findFile 后 file 的值仍然为 nil。如果我做错了什么或者这种方法不正确,请指教。

func example() { 
   var file *os.File
   err = filepath.Walk("uploads", findFile(fileId, file))
   if err != nil {
       http.Error(w, err.Error(), http.StatusBadRequest)
       return
   }
}

func findFile(fileId string, file *os.File) func(path string, info os.FileInfo, err error) error {
    return func(path string, info os.FileInfo, err error) error {
        if err != nil {
             return err
        }

        if !info.IsDir() && isFileMatching(info.Name(), fileId) {
             file, err = os.Open(path)
             if err != nil {
                 return err
             }
        }
        return nil
    }

}

你改变的是指针变量的值,而不是指针指向的值。

应该是:

f, err := os.Open(path)
if err != nil {
    return err
}
*file = *f

注:

*file = *f实际上是一个os.File.

的副本

这不是一个好的做法。您可能需要考虑为此类工作使用通道(和协程)。

并且您可能还想检查是否只有一个路径可以通过 isFileMatching,或者是文件描述符泄漏(未关闭打开的文件)。

关于之前的回答可以使用slice来收集文件,不会复制,最后可以全部关闭。

func example() {
    var files []*os.File
    err := filepath.Walk("uploads", findFile(fileId, &files))
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }
}

func findFile(fileId string, files *[]*os.File) func(path string, info os.FileInfo, err error) error {
    return func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }

        if !info.IsDir() && isFileMatching(info.Name(), fileId) {
            file, err := os.Open(path)
            if err != nil {
                return err
            }
            *files = append(*files, file)
        }
        return nil
    }

}

另一种选择是filepath.WalkDir:

package main

import (
   "errors"
   "io/fs"
   "os"
   "path/filepath"
)

func open(root, name string) (*os.File, error) {
   var f *os.File
   filepath.WalkDir(root, func(s string, d fs.DirEntry, e error) error {
      if e != nil { return e }
      if d.Name() != name { return nil }
      f, e = os.Open(s)
      if e != nil { return e }
      return errors.New("found")
   })
   if f == nil {
      return nil, errors.New("not found")
   }
   return f, nil
}

func main() {
   f, e := open(`C:\go`, "path.go")
   if e != nil {
      panic(e)
   }
   defer f.Close()
   println(f.Name())
}

https://golang.org/pkg/path/filepath#WalkDir