精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Go 中如何高效遍歷目錄?探索幾種方法

開發 前端
在本文中,我們系統介紹了 Go 中多種遍歷目錄文件的方法。從傳統的 ioutil.ReadDir?,到 Go 1.16 引入的 os.ReadDir,os.File? 的 ReadDir? 方法。

目錄遍歷是一個很常見的操作,它的使用場景有如文件目錄查看(最典型的應用如 ls 命令)、文件系統清理、日志分析、項目構建等。

本文將嘗試逐步介紹在 Go 中幾種遍歷目錄文件的方法,從傳統的 ioutil.ReadDir 函數開始,逐漸深入。

圖片圖片

文中也會提供示例代碼、提供一些性能剖析,以便于大家更好地理解。

ioutil.ReadDir

首先,Go 中目錄文件遍歷的第一種方式是 ioutil.ReadDir 函數。

在 Go 1.16 版本前,ioutil.ReadDir 就是遍歷目錄的標準方法,它的返回結構是目錄中文件的 FileInfo 列表,簡單直接。

示例代碼:

func main() {
    files, err := ioutil.ReadDir(".")
    if err != nil {
        log.Fatal(err)
    }

    for _, f := range files {
        fmt.Println(f.Name())
    }
}

但它的缺點也非常明顯,性能不高。導致它的主要原因有如下幾點:

完全加載

這就導致了 ioutil.ReadDir 在返回結果前,會將目錄下所有文件的信息完全加載到內存中。對于包含大量文件的目錄,它就需要在內存中存儲大量的 FileInfo 對象,毫無疑問,這會增加內存使用。

FileInfo 開銷

由于是完全加載,每個 FileInfo 對象都包含了文件的詳細信息,如文件名、大小、修改時間等都會在返回之前都已經加載完成。但獲取這些信息需進行系統調用。而每個文件都要做這樣的調用,當文件數量很多時,這些系統調用的累積開銷可以變得不容忽視了。

無法分批處理

由于 ioutil.ReadDir 是一次性返回所有文件信息,沒有提供分批處理的能力。無論目錄中有多少文件,都要等待所有文件信息讀取完成,這在處理目錄中包含大量文件的場景中,也就無法提前并行處理,效率是可想而知的。

這一點其實和我們前面的一篇文章,介紹的 GO 中按行(或者說按塊)讀取文件的邏輯是類似的,一次加載全部內容,有潛在的性能問題。

由于 ioutil.ReadDir 有這么多的缺點,所以它在 Go 1.16 及更高版本已經被棄用了。

那現在我們該用什么方法呢?

os.ReadDir

從 Go 1.16 版本起,標準庫針對目錄遍歷查看提供了新的函數 os.ReadDir,以用來簡化和提高遍歷目錄文件的效率。

函數簽名如下:

func ReadDir(name string) ([]DirEntry, error)

os.ReadDir 函數返回一個按文件名排序的 DirEntry 類型切片。如果在讀取目錄項時遇到錯誤,它也會盡量返回已讀取內容。這種設計同時兼顧了效率和錯誤處理的需要。

示例代碼:

func main() {
    files, err := os.ReadDir(".")
    if err != nil {
        log.Fatal(err)
    }

    for _, file := range files {
        fmt.Println(file.Name())
    }
}

os.ReadDir 相比于舊方法 ioutil.ReadDir 的有什么優勢?為什么丟棄 ioutil.ReadDir 而引入這個新的 os.ReadDir。

如果對比兩者源碼,會發現差異主要在返回的類型上。os.ReadDir 返回的 []DirEntry 而非 []FileInfo。它還具有性能優勢。

為什么?

因為 DirEntry 允許按需獲取文件詳情,即懶加載,而非是遍歷目錄時立即加載所有文件屬性。很多場景下,我們并不需要

我在 MacOS 系統下測試的 DirEntry 接口的實際變量類型為 os.unixDirent。

它的源碼如下:

func (d *unixDirent) Name() string   { return d.name }
func (d *unixDirent) IsDir() bool    { return d.typ.IsDir() }
func (d *unixDirent) Type() FileMode { return d.typ }

func (d *unixDirent) Info() (FileInfo, error) {
    if d.info != nil {
        return d.info, nil
    }
    return lstat(d.parent + "/" + d.name)
}

我們只有在調用 Info 方法時,才會真正通過 lstat 發起系統調用。

如果你有將舊代碼遷移到 DirEntry 的需求, Go 1.17 還引入了 fs.FileInfoToDirEntry 函數,允許我們將 FileInfo 對象轉換為 DirEntry 對象。

info, _ := os.Stat("somefile")dirEntry := fs.FileInfoToDirEntry(info)

看到這,對于認真思考的朋友,或許已經發現我們還有一個問題沒解決,即 os.ReadDir 不是也不支持分批處理的能力嗎?

繼續往下看吧,我將介紹一個更底層的方法。

os.File 的 ReadDir 方法

我們知道 os.Open 是用于打開文件的,但其實它也可用于打開目錄。如果 os.Open 打開的是目錄,我們在它返回的 os.File 上調用 ReadDir 以查看目錄內容。

示例代碼:

func main() {
    dir, err := os.Open(".")
    if err != nil {
        log.Fatal(err)
    }
    defer dir.Close()

    files, err := dir.ReadDir(-1)
    if err != nil {
        log.Fatal(err)
    }

    for _, file := range files {
        fmt.Println(file.Name())
    }
}

如上的代碼其實類似于 os.ReadDir 內容的實現代碼。

os.ReadDir 源碼如下:

func ReadDir(name string) ([]DirEntry, error) {
    f, err := Open(name)
    if err != nil {
        return nil, err
    }
    defer f.Close()

    dirs, err := f.ReadDir(-1)
    sort.Slice(dirs, func(i, j int) bool { return dirs[i].Name() < dirs[j].Name() })
    return dirs, err
}

這種方法更底層,提供了更多的靈活性。我們就可以用它分批讀取目標。

如何實現呢?

核心就是那句的 dir.ReadDir(-1),它的入參指定了每次讀取文件的數量,而 -1 表示讀取目錄的所有內容。我們只要將 -1 改為分批讀取的數量即可,多次循環即可。

示例代碼:

func main() {
    dir, err := os.Open(".")
    if err != nil {
        log.Fatal(err)
    }
    defer dir.Close()

    for {
        files, err := dir.ReadDir(10) // 每批讀取10個條目
        if err == io.EOF {
            break // 遍歷完成
        }
        if err != nil {
            log.Fatal(err) // 處理其他錯誤
        }

        for _, file := range files {
            fmt.Println(file.Name())
        }
    }
}

這段代碼演示了如何使用 File.ReadDir 分批處理目錄中的文件。通過這種方式,可以更有效地管理內存使用。

補充一點

在寫這篇文章時,我發現 os.File 有兩個查看目錄的方法,分別是 Readdir 和 ReadDir。功能上的區別是新的 ReadDir 返回的是 []DirEntry,而 Readdir 返回的是 []FileInfo。

換句話說,ReadDir 本質上是 Readdir 的升級版。

它們的函數簽名,如下所示:

func (f *File) Readdir(n int) ([]FileInfo, error)
func (f *File) ReadDir(n int) ([]DirEntry, error)

這算是不支持可選參數和重載,但要解決兼容問題采取的措施嗎?真的是蚌埠住了。

目錄的遞歸遍歷

現在,還差最后一個內容沒有介紹,那就是遞歸目錄遍歷。

針對目錄的遞歸遍歷,Go 中提供了一個專門的函數,filepath.Walk。它可以遍歷指定目錄下的所有子目錄。

示例代碼:

func main() {
    err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }
        fmt.Println(path)
        return nil
    })
    if err != nil {
        fmt.Printf("error walking the path %v: %v\n", ".", err)
    }
}

我們通過遍歷的回調函數中在處理每個文件。它簡化了目錄的遞歸遍歷,但對于大型或深層次的目錄結構,同樣存在著提前加載 FileInfo 的問題。

針對這個問題,在 Go1.16 版本也引入了基于 DirEntry 版的 filepath.WalkDir 函數。

filepath.WalkDir 的函數簽名如下:

func WalkDir(root string, fn fs.WalkDirFunc) error

fs.WalkDirFunc 的定義如下:

type WalkDirFunc func(path string, d DirEntry, err error) error

新函數的遍歷回調參數是 DirEntry,而非 FileInfo。現在,filepath.WalkDir 也有了延遲加載 FileInfo 的能力了。

現在,我們再來看下這張圖。

圖片圖片

總結

在本文中,我們系統介紹了 Go 中多種遍歷目錄文件的方法。從傳統的 ioutil.ReadDir,到 Go 1.16 引入的 os.ReadDir,os.File 的 ReadDir 方法。每種方法適用于不同的場景,如何選擇要取決于你的需求、Go 版本、性能。如果你需要遞歸遍歷,也可以使用基于 DirEntry 的 filepath.WalkDir 實現,提高遍歷的性能。

引用鏈接

[1] Go 中如何遍歷目錄?探索幾種方法: https://www.poloxue.com/2024-02-22-list-directory-in-golang/

責任編輯:武曉燕 來源: 碼途漫漫
相關推薦

2021-03-08 09:32:04

Python文件命令

2018-08-09 20:47:41

2021-06-08 11:42:12

Pandas數據分析Python

2009-08-25 09:22:01

DataGridVie

2024-06-03 08:26:34

Android開發監聽器

2020-10-16 18:35:53

JavaScript字符串正則表達式

2009-09-18 12:29:55

2010-05-17 15:17:06

MySQL常用操作

2013-08-21 11:31:21

iPhone圖片方法

2010-06-03 08:55:43

LINQ

2024-10-07 09:03:15

2010-04-30 16:22:07

Unix終端

2010-01-22 14:46:25

C++語言

2010-10-26 09:23:03

Web Service

2013-02-25 14:46:49

2011-06-16 10:48:33

session

2020-08-24 08:05:47

JavaScriptJavaScript 頁面

2021-02-26 13:20:48

Shell空行Linux

2009-09-09 11:24:46

PHP實現MVC

2020-01-10 16:23:44

Springboot停止服務Java
點贊
收藏

51CTO技術棧公眾號

一女被多男玩喷潮视频| 91在线网站视频| 在线不卡av电影| 91亚洲视频| 自拍偷拍亚洲综合| 国产一区二区视频在线免费观看| 男女视频免费看| heyzo久久| 精品成人a区在线观看| 久久久精品国产| 在线播放国产精品| 尤物av无码色av无码| av资源在线观看免费高清| 国产成人亚洲综合色影视| 2019中文在线观看| 久久国产美女视频| 国产精选一区| 亚洲成人网av| www.成年人| 亚洲www.| 精品久久久久久久久久国产| 亚洲在线色站| 男男激情在线| 成人国产电影网| 91九色蝌蚪国产| 亚洲精品成人在线视频| 激情欧美国产欧美| 日韩在线播放一区| 精品无码国产污污污免费网站| 999久久精品| 欧美日韩国产综合一区二区| 97成人在线观看视频| 日韩另类在线| 中文字幕五月欧美| 神马欧美一区二区| 蜜桃成人在线视频| 97se狠狠狠综合亚洲狠狠| av日韩免费电影| 国产精品特级毛片一区二区三区| 久久这里只有| 538国产精品视频一区二区| 激情综合五月网| 亚洲精品一二三区区别| 日韩网站免费观看| 美国一级黄色录像| 第一会所sis001亚洲| 亚洲免费视频在线观看| 污片免费在线观看| 久久97精品| 亚洲第一视频在线观看| 亚洲av午夜精品一区二区三区| 亚洲欧洲专区| 7878成人国产在线观看| 91av视频免费观看| 欧美综合影院| 欧美日韩dvd在线观看| 欧美日韩亚洲自拍| 国产成人亚洲一区二区三区| 欧美中文字幕一区二区三区| 不卡av免费在线| 国产成人免费9x9x人网站视频| 一本色道亚洲精品aⅴ| 欧美视频第一区| 欧美片第1页| 欧美伊人精品成人久久综合97| 91热这里只有精品| 久久久国产精品网站| 欧美三日本三级三级在线播放| 在线观看免费黄网站| 亚洲国产aⅴ精品一区二区三区| 欧美日韩视频在线第一区| 手机av在线网| 综合激情网...| 亚洲国产一区二区三区在线观看| 精品无码国产一区二区三区51安| 蜜桃久久久久| 亚洲石原莉奈一区二区在线观看| 国产精品美女高潮无套| 久久国产中文字幕| 欧美黑人一区二区三区| 国产一区二区三区影院| 视频在线观看一区二区三区| 国产精品永久免费视频| 国产熟女一区二区三区五月婷| 豆国产96在线|亚洲| 久久久久久久免费| 天堂中文8资源在线8| 一区二区三区欧美日| 好吊妞无缓冲视频观看| 国产三级一区| 精品国产乱码久久久久久夜甘婷婷 | 亚洲伊人第一页| 亚洲 另类 春色 国产| 久久久久国产精品厨房| 中文字幕中文字幕在线中心一区| 牛牛电影国产一区二区| 色综合中文字幕国产| 五月激情婷婷在线| 国产无遮挡裸体免费久久| 伊人久久久久久久久久久| 欧美激情图片小说| 老牛影视一区二区三区| 99伊人久久| 大地资源中文在线观看免费版| 亚洲精品视频一区二区| www.国产区| 操欧美女人视频| 最近2019中文字幕第三页视频| 精品少妇一二三区| 全国精品久久少妇| 国产传媒一区二区| 国产高清一区在线观看| 一区二区三区免费| 日本888xxxx| 91九色鹿精品国产综合久久香蕉| 一本色道久久综合亚洲精品小说| 久草福利资源在线观看| 欧美a级一区二区| 国产精品综合久久久久久| lutube成人福利在线观看| 亚洲大片精品永久免费| 黄色一级大片在线观看| 婷婷视频一区二区三区| 亚洲一级免费视频| 欧美亚韩一区二区三区| 精品一区二区三区免费毛片爱| 国产精品一区视频| 日本中文字幕在线看| 欧美中文字幕亚洲一区二区va在线| 国产精品偷伦视频免费观看了| 欧美一二区在线观看| 亚洲3p在线观看| 国产91视频在线| 中文字幕成人av| 欧美日韩二三区| 精品少妇3p| 九九热这里只有精品6| 国产suv精品一区二区33| 岛国精品在线观看| 自拍偷拍亚洲色图欧美| av高清一区| 亚洲黄色在线看| 青青草偷拍视频| 久久99精品国产| 亚洲成人午夜在线| 伊人色综合一区二区三区影院视频 | 久久亚洲精品人成综合网| 亚洲欧美日韩精品| 成人毛片18女人毛片| 成人在线综合网站| 成人污网站在线观看| 中文字幕成人| 日韩一区二区三区国产| 制服丝袜在线一区| 中文字幕av一区二区三区高| 91精品91久久久中77777老牛| 成人h动漫精品一区二区器材| 欧美成年人视频网站欧美| 亚洲熟女乱色一区二区三区久久久| 久久久久久久综合色一本| av免费中文字幕| 色婷婷精品视频| 91国内在线视频| 人妻丰满熟妇av无码区hd| 亚洲国产精品久久艾草纯爱| 日本少妇一区二区三区| 自拍欧美日韩| 成人一区二区三区四区| 欧美aaaaaaa| 精品久久国产老人久久综合| 青娱乐91视频| www.日韩av| 成人午夜视频免费在线观看| 日韩精品一区二区三区免费观看| 国产精品爽爽爽爽爽爽在线观看| 欧美激情办公室videoshd| 欧美日韩国产天堂| 亚洲熟女少妇一区二区| 激情欧美一区二区| 无码人妻精品一区二区蜜桃网站| 国产福利资源一区| 欧美一区二三区| 日本一级在线观看| 欧美中文字幕亚洲一区二区va在线| 综合 欧美 亚洲日本| 麻豆精品视频在线观看免费| 亚洲天堂第一区| 欧美挤奶吃奶水xxxxx| 欧美亚洲视频一区二区| 成人综合影院| 欧美一区二区成人| 国产香蕉在线视频| 欧美国产日韩在线观看| 亚洲欧美日韩三级| 亚洲精品九九| 性欧美videosex高清少妇| 久久精品黄色| 国模视频一区二区| 中文字幕日本在线观看| 精品久久久久久久久久久久包黑料 | 国产h视频在线播放| 欧美一区三区| 国产日韩欧美中文| 丝袜老师在线| 精品久久国产精品| 五月天婷婷社区| 欧美色综合网站| 久久久美女视频| 久久久三级国产网站| 在线免费黄色小视频| 国产精品免费看| 日韩第一页在线观看| 免费福利视频一区| 91天堂在线视频| 成人性生活视频| 国精产品一区一区三区有限在线| 国产精品一区在线看| 日韩区在线观看| 免费观看日批视频| 亚洲成人av一区二区| 欧美人与性囗牲恔配| 国产成人精品影视| 91丨九色丨蝌蚪| 喷水一区二区三区| 黄色免费福利视频| 午夜精品影院| 91制片厂免费观看| 精品国产乱码久久久久久果冻传媒| 国产精品一级久久久| 亚洲成人高清| 日本一区二区在线播放| 伦理在线一区| 久久激情视频免费观看| 午夜视频在线看| 国产亚洲人成网站在线观看| 亚洲乱熟女一区二区| 欧美精品日日鲁夜夜添| 无码人妻丰满熟妇精品区| 一区二区三区在线观看国产| 中国毛片直接看| 国产精品青草综合久久久久99| 日本黄色动态图| 成人少妇影院yyyy| 免费看的av网站| 羞羞视频在线观看欧美| 欧洲黄色一级视频| 激情欧美一区| www.xxx麻豆| 在线中文字幕亚洲| 在线观看欧美激情| 91亚洲国产| 日韩中文一区二区三区| 亚洲动漫在线观看| 欧美日韩一区二区三区在线观看免| 白白在线精品| 3d精品h动漫啪啪一区二区| 欧洲一区在线| 99久久自偷自偷国产精品不卡| 成人噜噜噜噜| 91久久久国产精品| 清纯唯美激情亚洲| 精品国产一二| 日韩欧美中文字幕电影| 久久国产精品一区二区三区| 日韩av资源网| 欧美精品v日韩精品v国产精品| 网曝91综合精品门事件在线| 久久久久se| 国产一区二区三区91| 日韩欧美精品久久| 日本欧美国产| 中文字幕在线亚洲三区| 亚洲天堂免费| bt天堂新版中文在线地址| 91久久亚洲| 亚洲熟妇av日韩熟妇在线| 另类天堂av| 午夜宅男在线视频| 丁香婷婷综合网| 亚洲观看黄色网| 国产亚洲精品超碰| 手机av在线看| 亚洲国产精品精华液网站| 精品国产一区二区三区四| 日本高清不卡视频| 国产精品伦理一区| 精品国产一区二区三区忘忧草 | 日韩av免费观影| 亚洲欧洲日产国产网站| 日本a级在线| 久久久久久中文| 精品亚洲a∨| 成人综合色站| 国产欧美日韩在线观看视频| 亚洲精品一区二区三区蜜桃久| 久久精品国产大片免费观看| 久久黄色片视频| 美腿丝袜亚洲一区| 国产精品欧美性爱| 久久久国产午夜精品 | 六月丁香久久丫| 日韩福利影院| 亚洲网站在线| 成人性生交免费看| www.成人网.com| 亚洲色图100p| 午夜亚洲国产au精品一区二区| 久久免费激情视频| 日韩欧美国产精品| 成年人在线视频免费观看| 欧美日韩国产成人在线观看| 625成人欧美午夜电影| 91久久精品视频| 精品一区av| 亚洲熟妇无码一区二区三区导航| 免费精品视频在线| 久久久久亚洲av无码专区首jn| 国产精品天美传媒沈樵| 日本少妇毛茸茸高潮| 欧美挠脚心视频网站| 偷拍自拍在线| 亚洲你懂的在线视频| 日本一二三区不卡| 欧美日本一区二区三区| 三级视频在线| 欧美精品18videos性欧| 国产精品诱惑| 日韩欧美精品久久| 美女视频一区免费观看| 男女性杂交内射妇女bbwxz| 国产精品久久久久毛片软件| 天堂网中文字幕| 精品粉嫩超白一线天av| 免费观看成人高潮| 国产精品视频自在线| jizz18欧美18| 青青在线视频免费观看| 国内成人精品2018免费看| 亚洲黄色免费视频| 欧美日韩中文字幕日韩欧美| 丰满熟妇乱又伦| 欧美情侣性视频| 日本国产亚洲| 一区二区三区av| 狠狠色丁香久久婷婷综| 91视频免费在观看| 在线精品视频免费播放| 清纯唯美亚洲色图| 国产成人jvid在线播放| 日韩高清在线免费观看| 91动漫在线看| 成人污视频在线观看| 日本在线视频免费观看| 欧美成人精品3d动漫h| 黄色一级片在线观看| 成人两性免费视频| 色男人天堂综合再现| 善良的小姨在线| 亚洲人成精品久久久久久| 一级黄色片在线观看| 操91在线视频| 亚洲精品不卡在线观看| www.xxx麻豆| av影院午夜一区| 不卡av电影在线| 尤物tv国产一区| 欧美视频精品| av不卡在线免费观看| 国产专区综合网| 午夜国产福利视频| 欧美一区二区三区爱爱| 三区四区电影在线观看| 亚洲综合中文字幕68页| 欧美日韩在线大尺度| 特级特黄刘亦菲aaa级| 一区二区三区高清在线| 欧美黄色小说| 国产精品欧美在线| 午夜欧美在线| 久久午夜夜伦鲁鲁片| 日韩欧美中文在线| 成年人视频在线观看免费| 成人黄色中文字幕| 国产精品视频| 你懂得视频在线观看| 日韩美女主播在线视频一区二区三区| 国产不卡人人| 亚洲精品永久www嫩草| 国产精品亚洲午夜一区二区三区| 精品视频久久久久| 自拍偷拍亚洲区| 日韩高清二区| av免费在线播放网站| 中文字幕不卡在线播放| 人妻妺妺窝人体色www聚色窝| 国产福利精品视频| 综合久久99| 国产 欧美 在线| 日韩欧美国产1| 日韩和的一区二在线|