使用新的 io.FS 到 fs.WalkDir 并列出跨文件系统类型的文件

问题描述 投票:0回答:1

我使用新的 io.FS 抽象来遍历文件系统并读取与我们内部文件扩展名匹配的每个文件的前 128 个字节。

这些文件位于本地文件系统和存档文件等中(ZIP 和 Tar 我认为)。

我正在使用 fs.WalkDir,传入 fs.FS (在我的测试中是 os.DIR 和 fstest.MapFS)。行走时,我返回一组“文件”(实际上它们是 *.pzix 和 *.pzi 文件,它们是我们的专有格式)。我找不到使用 FS 接口获取有关我正在处理的文件的一些信息的合适方法。

我想要:

  • 获取文件名
  • 获取文件大小
  • 获取openfile方法

我发现 Go 中来自 Java/C# 的接口有点令人困惑。我希望对抽象进行操作,但我不知道如何获取文件本身的其他实现(例如,文件接口有 Stat() 和 read)。

我发现的最简单的事情是将路径和文件名存储在数组中,然后当我迭代数组时,确定它是 os.Dir 还是 fstest.MapFS,但这似乎相当违反直觉:

func collectFiles(f fs.FS, root string) []string {
 var files []string
 fs.WalkDir(f, ".", func(p string, d fs.DirEntry, err error) error {
  if !d.IsDir() { // we also check a few other things in the filename here
   f = filepath.Abs(path.Join(root, p))
   files = append(files, f)
  }
 }
 return files
}

这给了我:

root =“m://”//mapfs 文件= {“m://id-198271.pzi”,“m://id-7125-092581.pzix”}

有没有更聪明的方法让我处理抽象而不做这些事情?因为返回数组后,我必须“打开”文件,读取前 128 个字节(签名)并对文件的其余部分进行哈希处理以确保其“有效”。

go io
1个回答
0
投票

获取文件名

p
是文件系统中的名称。

获取文件大小

致电

fs.Stat(f, p)

获取尺寸

获取openfile方法

使用

f.Open(p)

打开文件

示例:

f := os.DirFS("/etc")
fs.WalkDir(f, ".", func(p string, d fs.DirEntry, err error) error {
    if !d.IsDir() {
        s, _ := fs.Stat(f, p)
        r, _ := f.Open(p)
        defer r.Close()
        var buf [128]byte
        n, _ := io.ReadFull(r, buf[:])
        fmt.Printf("%s %d %q\n", p, s.Size(), buf[:n])
    }
    return nil
})

为了简洁起见,该示例忽略了错误。不要在实际代码中这样做。

https://go.dev/play/p/lPDuj6PgT6L

© www.soinside.com 2019 - 2024. All rights reserved.