欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang如何判斷文件是否存在

 更新時(shí)間:2024年11月26日 11:35:20   作者:apocelipes  
判斷一個(gè)文件是否存在是一個(gè)相當(dāng)常見的需求,在golang中也有多種方案實(shí)現(xiàn)這一功能,下面就跟隨小編一起學(xué)習(xí)一下具體的實(shí)現(xiàn)方法吧

判斷一個(gè)文件是否存在是一個(gè)相當(dāng)常見的需求,在golang中也有多種方案實(shí)現(xiàn)這一功能。

現(xiàn)在我們介紹其中兩種最常用也是最簡單的實(shí)現(xiàn),第一種將是跨平臺(tái)通用的,而第二種則在POSIX平臺(tái)上通用。

跨平臺(tái)實(shí)現(xiàn)

跨平臺(tái)實(shí)現(xiàn)的思路很簡單,如果某個(gè)文件不存在,那么使用os.Lstat就一定會(huì)返回error,只要判斷error是否代表文件不存在即可。

也許你注意到了有些代碼會(huì)使用os.Open來完成上述工作,不過最好不要這么做,因?yàn)殡m然兩者完成的功能沒有區(qū)別,但open和stat的調(diào)用開銷是不同的,后者要小于前者,而且對于判斷文件是否存在,檢查它的元數(shù)據(jù)要比直接嘗試打開它更加合理。

那么來看看實(shí)現(xiàn)的代碼:

func FileExist(path string) bool {
  _, err := os.Lstat(path)
  return !os.IsNotExist(err)
}

代碼很簡單,對于Windows/Linux/MacOS等是通用的,一般沒有特殊需求我也比較推薦這種實(shí)現(xiàn)。

POSIX平臺(tái)實(shí)現(xiàn)

如果你的程序是面向POSIX平臺(tái)的(例如UNIX、Linux等),那么還有一種更簡單的方案——syscall.Access

syscall.Access提供了用戶檢查文件元信息的手段,通常它被用來檢查文件權(quán)限以及文件的存在性。

通過使用syscall.F_OK標(biāo)志檢查文件,如果不存在則會(huì)返回和os.Lstat一樣的error:

func FileExist(path string) bool {
  err := syscall.Access(path, syscall.F_OK)
  return !os.IsNotExist(err)
}

這種實(shí)現(xiàn)的最大優(yōu)勢在于它簡單而直觀,但是它無法在Windows上使用。

一些提示

首先當(dāng)我們的FileExist返回true時(shí),其實(shí)文件并不一定存在。

當(dāng)我們對目標(biāo)path中的某一部分沒有可讀權(quán)限時(shí),os.Lstatsyscall.Access同樣會(huì)返回error,不過這個(gè)error不會(huì)讓os.IsNotExist返回true。

當(dāng)文件不存在而你對文件所在的目錄或者它的上層目錄沒有訪問權(quán)限時(shí),FileExist依舊會(huì)返回true,bug就在這時(shí)發(fā)生了。所以重要的一點(diǎn)是在判斷文件是否存在前應(yīng)該先判斷自己對文件及其路徑是否有訪問權(quán)限。

其次syscall.Access只會(huì)使用運(yùn)行程序的用戶的uid和gid,這會(huì)導(dǎo)致setuid之類的權(quán)限失效,通常來說這是沒什么問題的,然而posix平臺(tái)上一般都會(huì)考慮euid和egid,因此你可能需要使用syscall.Faccessat做代替。你需要在深思熟慮后使用合適的系統(tǒng)調(diào)用。

性能測試

最后我們看看兩個(gè)方案的性能,我們以os.Open做為基準(zhǔn),分別測試先文件存在和不存在時(shí)的性能表現(xiàn):

func checkWithOpen(path string) bool {
	f, err := os.Open(path)
	if err != nil {
		return false
	}
	f.Close()
	return true
}

func checkWithLstat(path string) bool {
	_, err := os.Lstat(path)
	return !os.IsNotExist(err)
}

func checkWithAccess(path string) bool {
        err := syscall.Access(path, syscall.F_OK)
	return !os.IsNotExist(err)
}

func BenchmarkNotExists(b *testing.B) {
	for range b.N {
		checkWithOpen("/home/apocelipes/no-")
	}
}

func BenchmarkNotExistsLstat(b *testing.B) {
	for range b.N {
		checkWithLstat("/home/apocelipes/no-")
	}
}

func BenchmarkNotExistsAccess(b *testing.B) {
	for range b.N {
		checkWithAccess("/home/apocelipes/no-")
	}
}

func BenchmarkExists(b *testing.B) {
	for range b.N {
		checkWithOpen("/home/apocelipes/.zshrc")
	}
}

func BenchmarkExistsLstat(b *testing.B) {
	for range b.N {
		checkWithLstat("/home/apocelipes/.zshrc")
	}
}

func BenchmarkExistsAccess(b *testing.B) {
	for range b.N {
		checkWithAccess("/home/apocelipes/.zshrc")
	}
}

這是結(jié)果:

測試使用的文件系統(tǒng)類型是XFS。

可以看到open是最慢的,lstat比access慢了16%左右。從結(jié)果里也可以看到lstat需要額外返回一個(gè)os.FileInfo結(jié)構(gòu)導(dǎo)致了額外的內(nèi)存分配,所以整體上速度更慢。

但考慮到跨平臺(tái)以及兼容性,使用os.Lstat是更常見的做法。

以上就是golang如何判斷文件是否存在的詳細(xì)內(nèi)容,更多關(guān)于go判斷文件是否存在的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • golang基礎(chǔ)之Interface接口的使用

    golang基礎(chǔ)之Interface接口的使用

    這篇文章主要介紹了golang基礎(chǔ)之Interface接口的使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07
  • 關(guān)于golang指針的有限操作詳解

    關(guān)于golang指針的有限操作詳解

    傳統(tǒng)意義上來說,指針是一個(gè)指向某個(gè)確切的內(nèi)存地址的值,這個(gè)內(nèi)存地址可以是任何數(shù)據(jù)或代碼的起始地址,在Go語言中有幾種東西可以代表"指針",本文給大家介紹的是關(guān)于golang指針的有限操作,感興趣的同學(xué)可以參考一下
    2023-08-08
  • 詳解go中panic源碼解讀

    詳解go中panic源碼解讀

    這篇文章主要介紹了go中panic源碼解讀,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • 詳解Golang如何在編譯時(shí)注入版本信息

    詳解Golang如何在編譯時(shí)注入版本信息

    這篇文章主要為大家詳細(xì)介紹了Golang如何在編譯時(shí)實(shí)現(xiàn)注入版本信息,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的可以了解一下
    2023-06-06
  • go使用Viper管理配置文件的方法步驟

    go使用Viper管理配置文件的方法步驟

    在項(xiàng)目開發(fā)中,需要把一些配置配置提取出來,方便配置和管理,可以使用Viper工具,Viper 是 Go 應(yīng)用程序的完整配置解決方案,也支持從環(huán)境變量中讀取,本文給大家介紹了go使用Viper管理配置文件的方法步驟,需要的朋友可以參考下
    2024-07-07
  • 15個(gè)Golang中時(shí)間處理的實(shí)用函數(shù)

    15個(gè)Golang中時(shí)間處理的實(shí)用函數(shù)

    在Go編程中,處理日期和時(shí)間是一項(xiàng)常見任務(wù),涉及到精確性和靈活性,本文將介紹一系列實(shí)用函數(shù),它們充當(dāng)time包的包裝器,需要的可以參考下
    2024-01-01
  • Go?Excelize?API源碼解析GetSheetFormatPr使用示例

    Go?Excelize?API源碼解析GetSheetFormatPr使用示例

    這篇文章主要為大家介紹了Go?Excelize?API源碼解析GetSheetFormatPr使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Go利用GJSON組件解鎖JSON讀取新姿勢

    Go利用GJSON組件解鎖JSON讀取新姿勢

    Go 標(biāo)準(zhǔn)庫提供了 encoding/json 包用于處理 json 數(shù)據(jù),同時(shí)第三方庫 GJSON & SJSON 也在 json 處理方面表現(xiàn)出色,下面我們就來看看如何使用GJSON解鎖JSON讀取新方法吧
    2025-03-03
  • Go Java算法最大單詞長度乘積示例詳解

    Go Java算法最大單詞長度乘積示例詳解

    這篇文章主要為大家介紹了Go Java算法最大單詞長度乘積示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • 解決Go gorm踩過的坑

    解決Go gorm踩過的坑

    這篇文章主要介紹了解決Go gorm踩過的坑,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04

最新評論