php小编草莓推荐使用新的io.FS来操作文件系统,特别是在使用fs.WalkDir并列出跨文件系统类型的文件时。这个新的功能能够更加灵活地处理文件操作,让用户能够更方便地获取需要的文件信息。无论是在开发还是维护过程中,这个功能都能够大大提高效率,减少繁琐的操作。如果你想更深入了解如何使用这个功能,不妨继续阅读下去,我们将为你介绍详细的操作步骤和注意事项。
问题内容
我使用新的 io.FS 抽象来遍历文件系统并读取与我们内部文件扩展名匹配的每个文件的前 128 个字节。
这些文件位于本地文件系统和存档文件等(ZIP 和 Tar I thunk)中。
我正在使用 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
files = { "m://id-198271.pzi", "m://id-7125-092581.pzix"}
有没有更聪明的方法让我处理抽象而不做这些事情?因为返回数组后,我必须“打开”文件,读取前 128 个字节(签名)并对文件的其余部分进行哈希处理以确保其“有效”。
编辑:澄清一下, collectFiles
方法正在创建我们的主要文件命中列表,以便在另一种方法中处理。我希望将本地系统文件、zip 文件和 tar 文件传递到该方法中,以便它可以迭代存档中的文件并将它们添加到数组中。
希望有一个 File 接口,我可以存储在数组中而不是字符串中,以便后续调用者可以在不知道底层是什么的情况下执行 f.open() 。
解决方法
p
是文件系统中的名称。
通过调用fs.Stat(f, p)
获取大小
使用 f.Open(p)
打开文件
示例:
f := os.DirFS("/etc")
fs.WalkDir(f, ".", func(p string, d fs.DirEntry, err error) error {
if !d.IsDir() {
st, _ := fs.Stat(f, p)
r, _ := f.Open(p)
defer r.Close()
// Read prefix
var buf [md5.Size]byte
n, _ := io.ReadFull(r, buf[:])
// Hash remainder
h := md5.New()
_, _ = io.Copy(h, r)
s := h.Sum(nil)
fmt.Printf("%s %d %x %x\n", p, st.Size(), buf[:n], s)
}
return nil
})
为了简洁起见,该示例忽略了错误。不要在实际代码中这样做。
https://www.php.cn/link/b599e8250e4481aaa405a715419c8179
以上就是使用新的 io.FS 到 fs.WalkDir 并列出跨文件系统类型的文件的详细内容,更多请关注编程网其它相关文章!