Go 標準庫之 os(獲取文件狀態、獲取_修改文件權限、創建、刪除目錄和文件、獲取進程ID、設置獲取環境變量)

1. 概述

os 包提供了操作系統函數的不依賴平臺的接口。失敗的調用會返回錯誤值而非錯誤碼。通常錯誤值裏包含更多信息。例如,如果某個使用一個文件名的調用(如Open、Stat)失敗了,打印錯誤時會包含該文件名,錯誤類型將爲 *PathError ,其內部可以解包獲得更多信息。

type PathError struct {
    Op   string
    Path string
    Err  error
}

PathError 記錄一個錯誤,以及導致錯誤的路徑。

func (e *PathError) Error() string

2. type FileInfo

type FileInfo interface {
    Name() string       // 文件的名字(不含擴展名)
    Size() int64        // 普通文件返回值表示其大小;其他文件的返回值含義各系統不同
    Mode() FileMode     // 文件的模式位
    ModTime() time.Time // 文件的修改時間
    IsDir() bool        // 等價於Mode().IsDir()
    Sys() interface{}   // 底層數據來源(可以返回nil)
}

FileInfo 用來描述一個文件對象。

func Stat(name string) (fi FileInfo, err error)

Stat 返回一個描述 name 指定的文件對象的 FileInfo 。如果指定的文件對象是一個符號鏈接,返回的 FileInfo 描述該符號鏈接指向的文件的信息,本函數會嘗試跳轉該鏈接。如果出錯,返回的錯誤值爲 *PathError 類型。

3. type FileMode

FileModel 的方法主要用來進行判斷和輸出權限。

type FileMode uint32

FileMode 代表文件的模式和權限位。這些字位在所有的操作系統都有相同的含義,因此文件的信息可以在不同的操作系統之間安全的移植。不是所有的位都能用於所有的系統,唯一共有的是用於表示目錄的 ModeDir 位。

const (
    // 單字符是被String方法用於格式化的屬性縮寫。
    ModeDir        FileMode = 1 << (32 - 1 - iota) // d: 目錄
    ModeAppend                                     // a: 只能寫入,且只能寫入到末尾
    ModeExclusive                                  // l: 用於執行
    ModeTemporary                                  // T: 臨時文件(非備份文件)
    ModeSymlink                                    // L: 符號鏈接(不是快捷方式文件)
    ModeDevice                                     // D: 設備
    ModeNamedPipe                                  // p: 命名管道(FIFO)
    ModeSocket                                     // S: Unix域socket
    ModeSetuid                                     // u: 表示文件具有其創建者用戶id權限
    ModeSetgid                                     // g: 表示文件具有其創建者組id的權限
    ModeCharDevice                                 // c: 字符設備,需已設置ModeDevice
    ModeSticky                                     // t: 只有root/創建者能刪除/移動文件
    // 覆蓋所有類型位(用於通過&獲取類型位),對普通文件,所有這些位都不應被設置
    ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice
    ModePerm FileMode = 0777 // 覆蓋所有Unix權限位(用於通過&獲取類型位)
)

這些被定義的位是 FileMode 最重要的位。另外 9 個不重要的位爲標準 Unix rwxrwxrwx 權限(任何人都可讀、寫、運行)。這些(重要)位的值應被視爲公共 API 的一部分,可能會用於線路協議或硬盤標識:它們不能被修改,但可以添加新的位。

函數定義 函數說明
func (m FileMode) IsDir() bool IsDir報告m是否是一個目錄
func (m FileMode) IsRegular() bool IsRegular報告m是否是一個普通文件
func (m FileMode) Perm() FileMode Perm方法返回m的Unix權限位
func (m FileMode) String() string 返回m的字符串表示

使用示例:

func main() {
    // Stat 返回一個描述 name 指定的文件對象的 FileInfo
	fi, err := os.Stat("./test.log")
	if err != nil {
		fmt.Println(err)
	}

	fm := fi.Mode()	// 返回 FileMode 
	fmt.Println(fm.IsDir())     // false
	fmt.Println(fm.IsRegular()) // true
	fmt.Println(fm.Perm())      // -rw-rw----
	fmt.Println(fm.String())    // -rw-rw----
}

實際文件顯示:

wohu@wohu:~/GoCode/src/task$ ll
total 20
-rw-rw-r--  1 wohu wohu  250 5月  20 09:40 main.go
-rw-rw----  1 wohu wohu    0 5月  15 10:54 test.log

4. 主要函數

函數定義 函數說明
func Hostname() (name string, err error) Hostname返回內核提供的主機名。
func Environ() []string Environ返回表示環境變量的格式爲"key=value"的字符串的切片拷貝
func Getenv(key string) string Getenv檢索並返回名爲key的環境變量的值。如果不存在該環境變量會返回空字 符串
func Setenv(key, value string) error Setenv設置名爲key的環境變量。如果出錯會返回該錯誤
func Clearenv() Clearenv刪除所有環境變量(謹慎使用)
func Exit(code int) Exit讓當前程序以給出的狀態碼code退出。一般來說,狀態碼0表示成功,非0表示出錯。 程序會立刻終止,defer的函數不會被執行
func Getuid() int Getuid返回調用者的用戶ID
func Geteuid() int Geteuid返回調用者的有效用戶ID
func Getgid() int Getgid返回調用者的組ID
func Getegid() int Getegid返回調用者的有效組ID
func Getgroups() ([]int, error) Getgroups返回調用者所屬的所有用戶組的組ID
func Getpid() int Getpid返回調用者所在進程的進程ID
func Getppid() int Getppid返回調用者所在進程的父進程的進程ID

使用示例:

func main() {
	hostname, err := os.Hostname()
	if err != nil {
		fmt.Println(err)
	}

	env := os.Environ()
	goroot := os.Getenv("GOROOT")
	uid := os.Getuid()
	euid := os.Geteuid()
	gid := os.Getgid()
	egid := os.Getegid()
	groups, err := os.Getgroups()
	if err != nil {
		fmt.Println(err)
	}

	pid := os.Getpid()
	ppid := os.Getppid()
	os.Exit(0)

	fmt.Println(hostname)
	fmt.Println(env)
	fmt.Println(goroot)
	fmt.Println(uid)
	fmt.Println(euid)
	fmt.Println(gid)
	fmt.Println(egid)
	fmt.Println(groups)
	fmt.Println(pid)
	fmt.Println(ppid)
}
func IsExist(err error) bool

返回一個布爾值說明該錯誤是否表示一個文件或目錄已經存在。 ErrExist 和一些系統調用錯誤會使它返回真。

func IsNotExist(err error) bool

返回一個布爾值說明該錯誤是否表示一個文件或目錄不存在。 ErrNotExist 和一些系統調用錯誤會使它返回真。

func IsPermission(err error) bool

返回一個布爾值說明該錯誤是否表示因權限不足要求被拒絕。 ErrPermission 和一些系統調用錯誤會使它返回真

func Getwd() (dir string, err error)

返回一個對應當前工作目錄的根路徑。如果當前目錄可以經過多條路徑抵達(因爲硬鏈接), Getwd 會返回其中一個。

func Chdir(dir string) error

將當前工作目錄修改爲 dir 指定的目錄。如果出錯,會返回 *PathError 底層類型的錯誤。

代碼示例如下:

func main() {
	_, err := os.Stat("./test.log")
	if os.IsExist(err) {
		fmt.Println("test.log do not exist")
	}
	if os.IsNotExist(err) {
		fmt.Println("test.log exist")
	}

	curDir, err := os.Getwd()
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(curDir) // /home/wohu/GoCode/src/task

	err = os.Chdir("/opt/")
	if err != nil {
		fmt.Println(err)
	}
	chDir, err := os.Getwd()
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(chDir) // opt
}
func Chmod(name string, mode FileMode) error

修改 name 指定的文件對象的 mode 。如果 name 指定的文件是一個符號鏈接,它會修改該鏈接的目的地文件的 mode 。如果出錯,會返回 *PathError 底層類型的錯誤。

代碼示例:

func main() {
	// Stat 返回一個描述 name 指定的文件對象的 FileInfo
	fi, err := os.Stat("./test.log")
	if err != nil {
		fmt.Println(err)
	}

	fm := fi.Mode() // 返回 FileMode
	filePerm := fm.Perm()
	fmt.Println(filePerm) // 修改前權限爲  -rw-rw----

	err = os.Chmod("./test.log", 0755)
	if err != nil {
		fmt.Println(err)
	}

	fi, err = os.Stat("./test.log")
	if err != nil {
		fmt.Println(err)
	}
	filePerm = fm.Perm()
	fmt.Println(filePerm) // 修改後權限爲  -rwxr-xr-x
}
func Chown(name string, uid, gid int) error

修改 name 指定的文件對象的用戶 id 和組 id 。如果 name 指定的文件是一個符號鏈接,它會修改該鏈接的目的地文件的用戶 id 和組 id 。如果出錯,會返回 *PathError 底層類型的錯誤。

func Getgroups() ([]int, error) 返回調用者屬於的 group ,其和 chown 配合使用,改變文件屬於的 group

代碼示例:

func main() {
	fmt.Println(os.Getgroups())                //獲取調用者屬於的組  [4 24 27 30 46 108 124 1000]
	fmt.Println(os.Getgid())                   //獲取調用者當前所在的組 1000
	fmt.Println(os.Chown("tmp.txt", 1000, 46)) //更改文件所在的組
}
func Mkdir(name string, perm FileMode) error

使用指定的權限和名稱創建一個目錄,僅適用於創建父目錄存在且要創建的目錄不存在的情況。如果要創建的目錄已經存在,則會報錯,如果出錯,會返回 *PathError 底層類型的錯誤。

func MkdirAll(path string, perm FileMode) error

使用指定的權限和名稱創建一個目錄,包括任何必要的上級目錄,並返回 nil ,否則返回錯誤。權限位 perm 會應用在每一個被本函數創建的目錄上。如果 path 指定了一個已經存在的目錄, MkdirAll 不做任何操作並返回 nil

代碼示例:

func main() {

	errMsg := os.Mkdir("./testDir", 0775)
	if errMsg != nil {
		fmt.Println("創建目錄失敗", errMsg)
		return
	}

	errMsg2 := os.MkdirAll("./a/b", 0775)
	if errMsg2 != nil {
		fmt.Println("創建目錄失敗", errMsg2)
		return
	}
}
func Rename(oldpath, newpath string) error

修改一個文件的名字,移動一個文件。可能會有一些個操作系統特定的限制。

func Remove(name string) error

刪除 name 指定的文件或目錄。如果是目錄的話必須要求該目錄爲空才能刪除,否則會報錯,會返回 *PathError 底層類型的錯誤。

func RemoveAll(path string) error

刪除 path 指定的文件,或目錄及它包含的任何下級對象。它會嘗試刪除所有東西,除非遇到錯誤並返回。如果 path 指定的對象不存在, RemoveAll 會返回 nil 而不返回錯誤。

示例代碼如下:

func main() {
	err := os.Rename("a", "b")
	if err != nil {
		fmt.Println(err)
	}

	err = os.Remove("./b")
	if err != nil {
		fmt.Println(err)
	}

	err = os.RemoveAll("./b")
	if err != nil {
		fmt.Println(err)
	}
}

5. type file

type File struct {
    // 內含隱藏或非導出字段
}

File 代表一個打開的文件對象。

5.1 返回文件對象的函數

func Create(name string) (file *File, err error)

Create 採用模式 0666(任何人都可讀寫,不可執行)創建一個名爲 name 的文件,如果文件已存在會截斷它(爲空文件)。如果成功,返回的文件對象可用於 I/O ;對應的文件描述符具有 O_RDWR 模式。如果出錯,錯誤底層類型是 *PathError

func Open(name string) (file *File, err error)

Open 打開一個文件用於讀取。如果操作成功,返回的文件對象的方法可用於讀取數據;對應的文件描述符具有 O_RDONLY 模式。如果出錯,錯誤底層類型是 *PathError

func OpenFile(name string, flag int, perm FileMode) (file *File, err error)

OpenFile 是一個更一般性的文件打開函數,大多數調用者都應用 OpenCreate 代替本函數。它會使用指定的選項(如 O_RDONLY 等)、指定的模式(如 0666 等)打開指定名稱的文件。如果操作成功,返回的文件對象可用於 I/O 。如果出錯,錯誤底層類型是 *PathError

func NewFile(fd uintptr, name string) *File

NewFile 使用給出的 Unix 文件描述符和名稱創建一個文件。

func Pipe() (r File, w File, err error)

Pipe 返回一對關聯的文件對象。從 r 的讀取將返回寫入 w 的數據。本函數會返回兩個文件對象和可能的錯誤。

5.2 文件對象的方法

func (f *File) Name() string

Name 方法返回(提供給 Open/Create 等方法的)文件名稱。

func (f *File) Stat() (fi FileInfo, err error)

Stat 返回描述文件 fFileInfo 類型值。如果出錯,錯誤底層類型是 *PathError

func (f *File) Fd() uintptr

Fd 返回與文件 f 對應的整數類型的 Unix 文件描述符。

func (f *File) Chdir() error

Chdir 將當前工作目錄修改爲 ff 必須是一個目錄。如果出錯,錯誤底層類型是 *PathError

func (f *File) Chmod(mode FileMode) error

Chmod 修改文件的模式。如果出錯,錯誤底層類型是 *PathError

func (f *File) Chown(uid, gid int) error

Chown 修改文件的用戶 ID 和組 ID 。如果出錯,錯誤底層類型是 *PathError

func (f *File) Readdir(n int) (fi []FileInfo, err error)

Readdir 讀取目錄 f 的內容,返回一個有 n 個成員的 []FileInfo ,這些 FileInfo 是被 Lstat 返回的,採用目錄順序。對本函數的下一次調用會返回上一次調用剩餘未讀取的內容的信息。

如果 n>0Readdir 函數會返回一個最多 n 個成員的切片。這時,如果 Readdir 返回一個空切片,它會返回一個非 nil 的錯誤說明原因。如果到達了目錄 f 的結尾,返回值 err 會是 io.EOF

如果 n<=0Readdir 函數返回目錄中剩餘所有文件對象的 FileInfo 構成的切片。此時,如果 Readdir 調用成功(讀取所有內容直到結尾),它會返回該切片和 nil 的錯誤值。如果在到達結尾前遇到錯誤,會返回之前成功讀取的 FileInfo 構成的切片和該錯誤。

func (f *File) Readdirnames(n int) (names []string, err error)

Readdirnames 讀取並返回目錄 f 裏面的文件的名字切片。

如果 n>0Readdirnames 返回最多 n 個名字。在這種情況下,如果 Readdirnames 返回一個空的切片,它會返回一個非空的錯誤來解釋原因。在目錄的結尾,錯誤爲 EOF

如果 n<0Readdirnames 返回目錄下所有的文件的名字,用一個切片表示。在這種情況下,如果用一個切片表示成功(讀取直到目錄結尾),它返回切片和一個空的錯誤。如果在目錄結尾之前遇到了一個錯誤, Readdirnames 返回直到當前所讀到的 names 和一個非空的錯誤。

func (f *File) Truncate(size int64) error

Truncate 改變文件的大小,它不會改變 I/O 的當前位置。 如果截斷文件,多出的部分就會被丟棄。如果出錯,錯誤底層類型是 *PathError

func (f *File) Read(b []byte) (n int, err error)

Read 方法從 f 中讀取最多 len(b) 字節數據並寫入 b 。它返回讀取的字節數和可能遇到的任何錯誤。文件終止標誌是讀取 0 個字節且返回值 errio.EOF

func (f *File) ReadAt(b []byte, off int64) (n int, err error)

ReadAt 從指定的位置(相對於文件開始位置)讀取 len(b) 字節數據並寫入 b 。它返回讀取的字節數和可能遇到的任何錯誤。當 n<len(b) 時,本方法總是會返回錯誤;如果是因爲到達文件結尾,返回值 err 會是 io.EOF

func (f *File) Write(b []byte) (n int, err error)

Write 向文件中寫入 len(b) 字節數據。它返回寫入的字節數和可能遇到的任何錯誤。如果返回值 n!=len(b) ,本方法會返回一個非 nil 的錯誤。

func (f *File) WriteString(s string) (ret int, err error)

WriteString 類似 Write ,但接受一個字符串參數。

func (f *File) WriteAt(b []byte, off int64) (n int, err error)

WriteAt 在指定的位置(相對於文件開始位置)寫入 len(b) 字節數據。它返回寫入的字節數和可能遇到的任何錯誤。如果返回值 n!=len(b) ,本方法會返回一個非 nil 的錯誤。

func (f *File) Seek(offset int64, whence int) (ret int64, err error)

Seek 設置下一次讀/寫的位置。

參考:

https://studygolang.com/pkgdoc
https://www.cnblogs.com/sunailong/p/7554013.html
https://blog.csdn.net/weiyuefei/article/details/77892871

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章