php小編草莓建議使用新的io.FS來操作檔案系統,特別是在使用fs.WalkDir並列出跨檔案系統類型的檔案時。這個新的功能能夠更有彈性地處理文件操作,讓使用者更方便地取得所需的文件資訊。無論是在開發或維護過程中,這個功能都能大幅提高效率,減少繁瑣的操作。如果你想更深入了解如何使用這個功能,不妨繼續閱讀下去,我們將為你介紹詳細的操作步驟和注意事項。
我使用新的 io.FS 抽象來遍歷檔案系統並讀取與我們內部檔案副檔名相符的每個檔案的前 128 個位元組。
這些檔案位於本機檔案系統和存檔檔案等(ZIP 和 Tar I thunk)中。
我正在使用 fs.WalkDir,傳入 fs.FS (在我的測試中為 os.DIR 和 fstest.MapFS)。行走時,我返回一組「文件」(實際上它們是 *.pzix 和 *.pzi 文件,它們是我們的專有格式)。我找不到使用 FS 介面來獲取有關我正在處理的文件的一些資訊的合適方法。
我想要:
我發現 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 並列出跨檔案系統類型的文件的詳細內容。更多資訊請關注PHP中文網其他相關文章!