Go語言 | 你還在這樣獲取檔案的大小嗎?

flysnow發表於2020-07-28

在專案中,我們可能會需要獲取一個檔案的大小,在Golang(Go語言)中,有很多方法來獲取一個檔案的大小,看看你是否還在用最慢的方式。

Read位元組方式

第一種,是最直觀會想到的,也就是開啟檔案,把檔案讀取一遍。

func main() {
    file,err:=os.Open("water")
    if err ==nil {
        sum := 0
        buf:=make([]byte,2014)
        for  {
            n,err:=file.Read(buf)
            sum+=n
            if err==io.EOF {
                break
            }
        }
        fmt.Println("file size is ",sum)
    }
}

這種方式需要開啟檔案,通過for迴圈讀取檔案的位元組內容,然後算出檔案的大小,這樣時也是最不能用的辦法,因為效率低,程式碼量大。

ioutil方式

上面的程式碼比較囉嗦,這時候我們可能想到了使用ioutil包的ReadFile來代替,直接獲得檔案的內容,進而計算出檔案的大小。

func main() {
    content,err:=ioutil.ReadFile("water")
    if err == nil {
        fmt.Println("file size is ",len(content))
    }
}

通過ioutil.ReadFile函式,我們三行程式碼就可以搞定,的確方便很多,但是效率慢的問題依然,存在,如果是個很大的檔案呢?

Stat方法

繼續再進一步,我們不讀取檔案的內容來計算了,我們通過檔案的資訊

func main() {
    file,err:=os.Open("water")

    if err == nil {
        fi,_:=file.Stat()
        fmt.Println("file size is ",fi.Size())
    }
}

這種方式不會再讀取檔案的內容,而是通過Stat方法直接獲取,速度會非常快,尤其對於大檔案尤其有用。但是它還不是我們今天要講的終極辦法,因為它還是會開啟檔案,會佔用它。

終極方案

好了,我們的終極方案終於要登場了,他的程式碼也非常簡單。

func main() {
    fi,err:=os.Stat("water")
    if err ==nil {
        fmt.Println("file size is ",fi.Size(),err)
    }
}

是的,也只需要三行程式碼即可實現,這裡使用的是os.Stat,通過他可以獲得檔案的後設資料資訊,現在我們看看它能獲取到哪些資訊。

獲取檔案資訊

通過os.Stat方法,我們可以獲取檔案的資訊,比如檔案大小、名字等。

func main() {
    fi,err:=os.Stat("water")
    if err ==nil {
        fmt.Println("name:",fi.Name())
        fmt.Println("size:",fi.Size())
        fmt.Println("is dir:",fi.IsDir())
        fmt.Println("mode::",fi.Mode())
        fmt.Println("modTime:",fi.ModTime())
    }
}

執行這段程式碼看下結果:

name: water
size: 403
is dir: false
mode:: -rw-r--r--
modTime: 2018-05-06 18:52:07 +0800 CST

以上就是可以獲取到的檔案資訊,還包括判斷是否是目錄,許可權模式和修改時間。所以我們對於檔案的資訊獲取要使用os.Stat函式,它可以在不開啟檔案的情況下,高效獲取檔案資訊。

判斷檔案是否存在

os.Stat函式有兩個返回值,一個是檔案資訊,一個是err,通過err我們可以判斷檔案是否存在。

首先,err==nil的時候,檔案肯定是存在的;其次err!=nil的時候也不代表不存在,這時候我們就需要進行嚴密的判斷。

func main() {
    _,err:=os.Stat(".")
    if err ==nil {
        fmt.Println("file exist")
    }else if os.IsNotExist(err){
        fmt.Println("file not exist")
    }else{
        fmt.Println(err)
    }
}

通過os.IsNotExist來判斷一個檔案不存在。最後else的可能性比較少,這個時候可以看下具體的錯誤是什麼,再根據錯誤來判斷檔案是否存在。

小結

os.Stat是一個非常好的函式,可以讓我們非常高效的獲取檔案資訊,所以在專案中儘可能的使用它。

本文為原創文章,轉載註明出處,歡迎掃碼關注公眾號flysnow_org或者網站 www.flysnow.org/ ,第一時間看後續精彩文章。覺得好的話,請順手點個贊吧。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章