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
是一個更一般性的文件打開函數,大多數調用者都應用 Open
或 Create
代替本函數。它會使用指定的選項(如 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
返回描述文件 f
的 FileInfo
類型值。如果出錯,錯誤底層類型是 *PathError
。
func (f *File) Fd() uintptr
Fd
返回與文件 f
對應的整數類型的 Unix
文件描述符。
func (f *File) Chdir() error
Chdir
將當前工作目錄修改爲 f
, f
必須是一個目錄。如果出錯,錯誤底層類型是 *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>0
, Readdir
函數會返回一個最多 n
個成員的切片。這時,如果 Readdir
返回一個空切片,它會返回一個非 nil
的錯誤說明原因。如果到達了目錄 f
的結尾,返回值 err
會是 io.EOF
。
如果 n<=0
, Readdir
函數返回目錄中剩餘所有文件對象的 FileInfo
構成的切片。此時,如果 Readdir
調用成功(讀取所有內容直到結尾),它會返回該切片和 nil
的錯誤值。如果在到達結尾前遇到錯誤,會返回之前成功讀取的 FileInfo
構成的切片和該錯誤。
func (f *File) Readdirnames(n int) (names []string, err error)
Readdirnames
讀取並返回目錄 f
裏面的文件的名字切片。
如果 n>0
, Readdirnames
返回最多 n
個名字。在這種情況下,如果 Readdirnames
返回一個空的切片,它會返回一個非空的錯誤來解釋原因。在目錄的結尾,錯誤爲 EOF
。
如果 n<0
, Readdirnames
返回目錄下所有的文件的名字,用一個切片表示。在這種情況下,如果用一個切片表示成功(讀取直到目錄結尾),它返回切片和一個空的錯誤。如果在目錄結尾之前遇到了一個錯誤, 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 個字節且返回值 err
爲 io.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