我們在上一篇文章中。從“os.File類型都實作了哪些io包中的接口”這一問題出發,介紹了一系列的相關内容。今天我們繼續圍繞這一知識點進行擴充。
針對File值的操作模式主要有隻讀模式、隻寫模式和讀寫模式。
這些模式分别由常量os.O_RDONLY、os.O_WRONLY和os.O_RDWR代表。在我們建立或打開一個檔案的時候,必須把這三個模式中的一個設定為此檔案的操作模式。
除此之外,我們還可以為這裡的檔案設定額外的操作模式,可選項如下所示。
os.O_APPEND:當向檔案中寫入内容時,把新内容追加到現有内容的後邊。
os.O_CREATE:當給定路徑上的檔案不存在時,建立一個新檔案。
os.O_EXCL:需要與os.O_CREATE一同使用,表示在給定的路徑上不能有已存在的檔案。
os.O_SYNC:在打開的檔案之上實施同步 I/O。它會保證讀寫的内容總會與硬碟上的資料保持同步。
os.O_TRUNC:如果檔案已存在,并且是正常的檔案,那麼就先清空其中已經存在的任何内容。
對于以上操作模式的使用,os.Create函數和os.Open函數都是現成的例子。
os.Create函數在調用os.OpenFile函數的時候,給予的操作模式是os.O_RDWR、os.O_CREATE和os.O_TRUNC的組合。
這就基本上決定了前者的行為,即:如果參數name代表路徑之上的檔案不存在,那麼就建立一個,否則,先清空現存檔案中的全部内容。
并且,它傳回的File值的讀取方法和寫入方法都是可用的。這裡需要注意,多個操作模式是通過按位或操作符|組合起來的。
我在前面說過,os.Open函數的功能是:以隻讀模式打開已經存在的檔案。其根源就是它在調用os.OpenFile函數的時候,隻提供了一個單一的操作模式os.O_RDONLY。
以上,就是我對可應用于File值的操作模式的簡單解釋。在 demo88.go 檔案中還有少許示例,可供你參考。
我們已經知道,os.OpenFile函數的第三個參數perm代表的是權限模式,其類型是os.FileMode。但實際上,os.FileMode類型能夠代表的,可遠不隻權限模式,它還可以代表檔案模式(也可以稱之為檔案種類)。
由于os.FileMode是基于uint32類型的再定義類型,是以它的每個值都包含了 32 個比特位。在這 32 個比特位當中,每個比特位都有其特定的含義。
比如,如果在其最高比特位上的二進制數是1,那麼該值表示的檔案模式就等同于os.ModeDir,也就是說,相應的檔案代表的是一個目錄。
又比如,如果其中的第 26 個比特位上的是1,那麼相應的值表示的檔案模式就等同于os.ModeNamedPipe,也就是說,那個檔案代表的是一個命名管道。
實際上,在一個os.FileMode類型的值(以下簡稱FileMode值)中,隻有最低的 9 個比特位才用于表示檔案的權限。當我們拿到一個此類型的值時,可以把它和os.ModePerm常量的值做按位與操作。
這個常量的值是0777,是一個八進制的無符号整數,其最低的 9 個比特位上都是1,而更高的 23 個比特位上都是0。
是以,經過這樣的按位與操作之後,我們即可得到這個FileMode值中所有用于表示檔案權限的比特位,也就是該值所表示的權限模式。這将會與我們調用FileMode值的Perm方法所得到的結果值是一緻。
在這 9 個用于表示檔案權限的比特位中,每 3 個比特位為一組,共可分為 3 組。
從高到低,這 3 組分别表示的是檔案所有者(也就是建立這個檔案的那個使用者)、檔案所有者所屬的使用者組,以及其他使用者對該檔案的通路權限。而對于每個組,其中的 3 個比特位從高到低分别表示讀權限、寫權限和執行權限。
如果在其中的某個比特位上的是1,那麼就意味着相應的權限開啟,否則,就表示相應的權限關閉。
是以,八進制整數0777就表示:作業系統中的所有使用者都對目前的檔案有讀、寫和執行的權限,而八進制整數0666則表示:所有使用者都對目前檔案有讀和寫的權限,但都沒有執行的權限。
我們在調用os.OpenFile函數的時候,可以根據以上說明設定它的第三個參數。但要注意,隻有在建立檔案的時候,這裡的第三個參數值才是有效的。在其他情況下,即使我們設定了此參數,也不會對目标檔案産生任何的影響。
為了聚焦于os.File類型本身,我在這兩篇文章中主要講述了怎樣把 os.File 類型應用于正常的檔案。該類型的指針類型實作了很多io包中的接口,是以它的具體功用也就可以不言自明了。
通過該類型的值,我們不但可以對檔案進行各種讀取、寫入、關閉等操作,還可以設定下一次讀取或寫入時的起始索引位置。
在使用這個類型的值之前,我們必須先要建立它。是以,我為你重點介紹了幾個可以建立,并獲得此類型值的函數。
包括:os.Create、os.NewFile、os.Open和os.OpenFile。我們用什麼樣的方式建立File值,就決定了我們可以使用它來做什麼。
利用os.Create函數,我們可以在作業系統中建立一個全新的檔案,或者清空一個現存檔案中的全部内容并重用它。
在相應的File值之上,我們可以對該檔案進行任何的讀寫操作。雖然os.NewFile函數并不是被用來建立新檔案的,但是它能夠基于一個有效的檔案描述符包裝出一個可用的File值。
os.Open函數的功能是打開一個已經存在的檔案。但是,我們隻能通過它傳回的File值對相應的檔案進行讀操作。
os.OpenFile是這些函數中最為靈活的一個,通過它,我們可以設定被打開檔案的操作模式和權限模式。實際上,os.Create函數和os.Open函數都隻是對它的簡單封裝而已。
在使用os.OpenFile函數的時候,我們必須要搞清楚操作模式和權限模式所代表的真正含義,以及設定它們的正确方式。
我在本文的擴充問題中分别對它們進行了較為詳細的解釋。同時,我在對應的示例檔案中也編寫了一些代碼。
你需要認真地閱讀和了解這些代碼,并在運作它們的過程當中悟出這兩種模式的真谛。
我在本文中講述的東西對于os包來說,隻是海面上的那部分冰山而已。這個代碼包囊括的知識衆多,而且延展性都很強。
如果你想完全了解它們,可能還需要去參看作業系統等方面的文檔和教程。由于篇幅原因,我在這裡隻是做了一個引導,幫助你初識該包中的一些重要的程式實體,并給予你一個可以深入下去的切入點,希望你已經在路上了。
今天的思考題是:怎樣通過os包中的 API 建立和操縱一個系統程序?
https://github.com/MingsonZheng/go-core-demo

本作品采用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協定進行許可。
歡迎轉載、使用、重新釋出,但務必保留文章署名 鄭子銘 (包含連結: http://www.cnblogs.com/MingsonZheng/ ),不得用于商業目的,基于本文修改後的作品務必以相同的許可釋出。