日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

Go 中如何檢查文件是否存在?可能產(chǎn)生競態(tài)條件?

來源: 責(zé)編: 時間:2024-02-05 17:20:09 206觀看
導(dǎo)讀Go 中如何檢查文件是否存在呢?如果你用的是 Python,可通過 os.path.exists 這樣的標(biāo)準(zhǔn)庫函數(shù)實現(xiàn)。遺憾的是,Go 標(biāo)準(zhǔn)庫沒有提供這樣直接的函數(shù),但好在,沒有直接的,卻有不那么直接的方法。本文將基于這個話題展開,介紹 Go 中

Go 中如何檢查文件是否存在呢?aw528資訊網(wǎng)——每日最新資訊28at.com

如果你用的是 Python,可通過 os.path.exists 這樣的標(biāo)準(zhǔn)庫函數(shù)實現(xiàn)。遺憾的是,Go 標(biāo)準(zhǔn)庫沒有提供這樣直接的函數(shù),但好在,沒有直接的,卻有不那么直接的方法。aw528資訊網(wǎng)——每日最新資訊28at.com

本文將基于這個話題展開,介紹 Go 中如何檢查文件是否存在。aw528資訊網(wǎng)——每日最新資訊28at.com

另外,本文最后還會介紹一個小注意點,即在判斷文件是否存在時,如何避免中潛在的競態(tài)條件。aw528資訊網(wǎng)——每日最新資訊28at.com

os.Stat 檢查文件狀態(tài)

Go 標(biāo)準(zhǔn)庫雖然沒有提供類似于 os.Exist 這樣直接的函數(shù)檢查文件是否存在,但它提供另外一個函數(shù) os.Stat。aw528資訊網(wǎng)——每日最新資訊28at.com

os.Stat 函數(shù)的作用是獲取文件狀態(tài)信息,我們通過檢查它返回的錯誤即可知曉文件是否存在。aw528資訊網(wǎng)——每日最新資訊28at.com

圖片圖片aw528資訊網(wǎng)——每日最新資訊28at.com

示例代碼,如下所示:aw528資訊網(wǎng)——每日最新資訊28at.com

func main() {  _, err := os.Stat("/path/to/file")  if err != nil {    if os.IsNotExist(err) {      // 文件不存在    } else {      // 其他錯誤    }  }  // 文件存在}

第一個返回值表示文件信息,不是我們關(guān)心的重點,直接省略掉。aw528資訊網(wǎng)——每日最新資訊28at.com

第二個返回值表示錯誤 error。如果文件不存在,可通過檢查 os.IsNotExist 檢查 error 是否是 os.ErrNotExist,確定文件是否存在。aw528資訊網(wǎng)——每日最新資訊28at.com

與 C 對比

上面的示例中,我們使用 os.Stat 函數(shù)獲取文件的狀態(tài),通過 errors.Is 判斷返回錯誤,如果是 os.ErrNotExist,則文件不存在。aw528資訊網(wǎng)——每日最新資訊28at.com

不得不說,這其實更底層更標(biāo)準(zhǔn)的做法。aw528資訊網(wǎng)——每日最新資訊28at.com

類似于 Python 等高級語言,提供 os.path.exist 主要是為了方便編程,提高效率。aw528資訊網(wǎng)——每日最新資訊28at.com

如果使用 Unix C 實現(xiàn)同樣的功能,示例代碼如下:aw528資訊網(wǎng)——每日最新資訊28at.com

#include <errno.h>#include <stdio.h>#include <sys/stat.h>int main() {  struct stat buffer;  int exist = stat("/path/to/file", &buffer);  if (exist != 0) {    if (errno == ENOENT) { /* 文件不存在*/ }     else { /* 其他錯誤 */ }    return 0;  }  // 文件存在  return 0;}

是不是和我們前面代碼基本是一個模子。aw528資訊網(wǎng)——每日最新資訊28at.com

Go1.13 以及之后推薦使用 errors.Is

自 Go 1.13 起,推薦使用 os.Stat 和 errors.Is 的組合。這種方法提供了更一致和靈活的錯誤處理方式。aw528資訊網(wǎng)——每日最新資訊28at.com

具體而言,即使是經(jīng)過包裹的錯誤,errors.Is 依然能夠識別。aw528資訊網(wǎng)——每日最新資訊28at.com

我期初認(rèn)為,os.IsNotExist 能識別包裹 error,但不太確定,于是寫了個代碼簡單測試了下。aw528資訊網(wǎng)——每日最新資訊28at.com

示例代碼,如下所示:aw528資訊網(wǎng)——每日最新資訊28at.com

_, err := os.Stat("/path/to/file")  // 這是一個不存在的文件路徑werr := fmt.Errorf("Main: %w", err) // 包裹生成新錯誤fmt.Println(os.IsNotExist(err))     // 返回 true,表示不存在,這是錯誤結(jié)果fmt.Println(os.IsNotExist(werr))    // 返回 false,表示存在fmt.Println(errors.Is(werr, os.ErrNotExist)) // 返回 true 表示不存在

測試結(jié)果都已寫在注釋中。aw528資訊網(wǎng)——每日最新資訊28at.com

如上可知, os.IsNotExist 只能識別最初的 error,如果錯誤經(jīng)過 fmt.Errorf 包裹,則必須使用 errors.Is 識別。aw528資訊網(wǎng)——每日最新資訊28at.com

圖片圖片aw528資訊網(wǎng)——每日最新資訊28at.com

一句話概括,os.IsNotExist 可以用,但有適用范圍,而 errors.Is 則更通用。aw528資訊網(wǎng)——每日最新資訊28at.com

這一般也同樣適用于其他類似的庫。aw528資訊網(wǎng)——每日最新資訊28at.com

直接使用 Open 避免競態(tài)條件

到這里,基本已經(jīng)解答了 Go 中如何檢查文件存在性的問題。aw528資訊網(wǎng)——每日最新資訊28at.com

但,我還想引入一個討論:并發(fā)場景下,如何避免檢查文件存在性時引入潛在的競態(tài)條件?aw528資訊網(wǎng)——每日最新資訊28at.com

簡言之,文件狀態(tài)可能在檢查和操作發(fā)生變化。aw528資訊網(wǎng)——每日最新資訊28at.com

圖片圖片aw528資訊網(wǎng)——每日最新資訊28at.com

什么是更好的做法呢?aw528資訊網(wǎng)——每日最新資訊28at.com

我們可以直接嘗試打開或操作文件,根據(jù)返回結(jié)果判斷錯誤。aw528資訊網(wǎng)——每日最新資訊28at.com

示例代碼如下:aw528資訊網(wǎng)——每日最新資訊28at.com

file, err := os.Open("/path/to/file")if err != nil {    if errors.Is(err, os.ErrNotExist) {        // 文件不存在    } else {        // 處理其他類型的錯誤    }}

如上代碼中,你通過 open 直接打開一個文件,如果文件不存在,os.Open 將返回一個錯誤,我們檢查 error 確定下一步的操作。aw528資訊網(wǎng)——每日最新資訊28at.com

通過這種方式,我們可以避免打開文件時引入競態(tài)條件。aw528資訊網(wǎng)——每日最新資訊28at.com

open 是原子操作?

讀到這里,可能有人不禁問,為什么 open 能避免競態(tài)條件呢?它是原子操作嗎?aw528資訊網(wǎng)——每日最新資訊28at.com

是的。aw528資訊網(wǎng)——每日最新資訊28at.com

圖片圖片aw528資訊網(wǎng)——每日最新資訊28at.com

系統(tǒng)調(diào)用都是原子操作,操作系統(tǒng)會保證操作過程不受到干擾。如果出現(xiàn)問題,也會進(jìn)行回滾操作.aw528資訊網(wǎng)——每日最新資訊28at.com

這一點對于 Open 同樣使用。aw528資訊網(wǎng)——每日最新資訊28at.com

當(dāng)我們使用 open 打開一個文件時,系統(tǒng)會確保在這個操作完成前,不會受其他操作干擾,包括如檢查文件是否存在、創(chuàng)建文件描述符、分配必要的資源等。aw528資訊網(wǎng)——每日最新資訊28at.com

結(jié)論

本文通過一個小小的問題:Go 語言中如何檢查文件是否存在,除了引出 Go 中檢查文件是否存在的基本方法。同時,還介紹了文件操作時如何避免潛在的競態(tài)條件,進(jìn)一步了解到一個有趣的小知識,Unix 系統(tǒng)調(diào)用是原子性操作。aw528資訊網(wǎng)——每日最新資訊28at.com

最后,還是希望本文能幫助各位在 GO 語言的學(xué)習(xí)道路上起到一點微末作用。aw528資訊網(wǎng)——每日最新資訊28at.com

博客地址:Go 中如何檢查文件是否存在?可能產(chǎn)生競態(tài)條件?[1]aw528資訊網(wǎng)——每日最新資訊28at.com

引用鏈接

[1] Go 中如何檢查文件是否存在?可能產(chǎn)生競態(tài)條件?: https://www.poloxue.com/posts/2024-02-05-check-if-file-exists-in-golang/aw528資訊網(wǎng)——每日最新資訊28at.com

aw528資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-74190-0.htmlGo 中如何檢查文件是否存在?可能產(chǎn)生競態(tài)條件?

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: ?Thread Local深度解析,你學(xué)會了嗎?

下一篇: 100000行級別數(shù)據(jù)的 Excel 導(dǎo)入優(yōu)化之路

標(biāo)簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 怀仁县| 虞城县| 盐池县| 永济市| 东辽县| 灵璧县| 阿坝| 文水县| 古丈县| 万宁市| 蒙阴县| 南投市| 汶川县| 徐闻县| 合阳县| 凤阳县| 建阳市| 宜兰市| 临高县| 逊克县| 富顺县| 岫岩| 北宁市| 蕲春县| 饶平县| 兴安盟| 福鼎市| 贞丰县| 黑水县| 金门县| 安福县| 邯郸市| 昔阳县| 巫溪县| 平果县| 固镇县| 阿克陶县| 沙雅县| 都兰县| 伊川县| 江源县|