「Golang成長之路」標準庫之os包

ice_moss發表於2022-07-26

文章介紹

在該系列文章中我們學習了go的基礎語法、資料結構、面向”物件“程式設計和併發程式設計,現在我們來系統的學習go語言的標準庫的學習,在本文中將介紹到許可權,目錄,檔案的開啟和關閉,檔案的讀\寫、程式相關和環境相關

許可權

許可權perm,在建立檔案時才需要指定,不需要建立新檔案時可以將其設定為0

許可權項 檔案型別 執行 執行 執行
字元表示 (d|l|c|s|p) r w x r w x r w x
數字表示 4 2 1 4 2 1 4 2 1
許可權分配 檔案所有者 檔案所有者 檔案所有者 檔案所屬組使用者 檔案所屬組使用者 檔案所屬組使用者 其他使用者 其他使用者 其他使用者

go語言在syscall包中定義了很多關於檔案操作的許可權的常量例如(部分);

const (
    O_RDONLY int = syscall.O_RDONLY // 只讀模式開啟檔案
    O_WRONLY int = syscall.O_WRONLY // 只寫模式開啟檔案
    O_RDWR   int = syscall.O_RDWR   // 讀寫模式開啟檔案
    O_APPEND int = syscall.O_APPEND // 寫操作時將資料附加到檔案尾部
    O_CREATE int = syscall.O_CREAT  // 如果不存在將建立一個新檔案
    O_EXCL   int = syscall.O_EXCL   // 和O_CREATE配合使用,檔案必須不存在
    O_SYNC   int = syscall.O_SYNC   // 開啟檔案用於同步I/O
    O_TRUNC  int = syscall.O_TRUNC  // 如果可能,開啟時清空檔案
)

目錄

os.Create方法建立檔案
func Create(name string) (*File, error)

例項:

//CreateFile 建立檔案
func CreateFile(name string) {
    file, err := os.Create(name)
    if err != nil {
        fmt.Printf("err: %v\n", err)
    } else {
        fmt.Printf("file:%v\n", file)
    }
}
func main() {
    name := "/Users/feng/go/src/StudyGin/OSlearn/hello_test.txt"
    CreateFile(name)
}
建立目錄

建立的單個目錄:

func Mkdir(name string, perm FileMode) error

例項:

//CreateDir 建立單個目錄
func CreateDir(name string) {
    err := os.Mkdir(name, os.ModePerm)
    if err != nil {
        fmt.Printf("err:%v\n", err)
    }
}

建立多級目錄:

func MkdirAll(path string, perm FileMode) error

例項:

//CreateDirAll 建立多級目錄
func CreateDirAll(name string) {
    err := os.MkdirAll(name, os.ModePerm)
    if err != nil {
        fmt.Printf("err:%v\n", err)
    }
}
刪除目錄

刪除單個空目錄或檔案:

func Remove(name string) error

例項:

//RemoveDir 刪除單個空目錄或檔案
func RemoveDir(name string) {
    err := os.Remove(name)
    if err != nil {
        fmt.Printf("err:%v\n", err)
    }
}

強制刪除當前目錄下所有目錄:

func RemoveAll(path string) error

例項:

//RemoveDirAll 強制刪除所有目錄
func RemoveDirAll(name string) {
    err := os.RemoveAll(name)
    if err != nil {
        fmt.Printf("err:%v\n", err)
    }
}
os.Getwd()獲取當前目錄
func Getwd() (dir string, err error)

例項:

//GetWd 獲取當前目錄
func GetWd() {
    dir, err := os.Getwd()
    if err != nil {
        fmt.Printf("err:%v\n", err)
    } else {
        fmt.Printf("dir:%v\n", dir)
    }
}
os.Chdir()修改當前工作目錄
func Chdir(dir string) error

例項:

//ChWd 修改當前工作目錄
func ChWd() {
    err := os.Chdir("d:/")
    if err != nil {
        fmt.Printf("err: %v\n", err)
    }
    fmt.Println(os.Getwd())
}
os.TempDir()獲取臨時檔案
func TempDir() string

例項:

//TemDir 獲取臨時檔案目錄
func TemDir() {
    fmt.Println(os.TempDir())
}
os.Rename()修改檔名
func Rename(oldpath string, newpath string) error

例項:

//RenameFile 修改檔名
func RenameFile(oldpath, Newpath string) {
    err := os.Rename(oldpath, Newpath)
    if err != nil {
        fmt.Printf("err:%v\n", err)
    }
}

檔案讀操作

對於檔案的讀/寫操作我們,我們需要擁有相關許可權,才能對檔案進行讀/寫

這裡我們定義一些關於許可權的常量:

const (
    O_RDONLY int = syscall.O_RDONLY // 只讀模式開啟檔案
    O_WRONLY int = syscall.O_WRONLY // 只寫模式開啟檔案
    O_RDWR   int = syscall.O_RDWR   // 讀寫模式開啟檔案
    O_APPEND int = syscall.O_APPEND // 寫操作時將資料附加到檔案尾部
    O_CREATE int = syscall.O_CREAT  // 如果不存在將建立一個新檔案
    O_EXCL   int = syscall.O_EXCL   // 和O_CREATE配合使用,檔案必須不存在
    O_SYNC   int = syscall.O_SYNC   // 開啟檔案用於同步I/O
    O_TRUNC  int = syscall.O_TRUNC  // 如果可能,開啟時清空檔案
)
開啟檔案

預設開啟方式:

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

os.Open()返回一個File物件的指標

例項:

//Open 只讀檔案,不能寫
func Open(name string) {
    file, err := os.Open(name)
    if err != nil {
        fmt.Printf("err:%v\n", err)
    } else {
        fmt.Printf("file:%s\n", file)
    }
}

以指定許可權開啟

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

例項:

//OpenFile 以指定許可權開啟
func OpenFile(name string, perm os.FileMode) {
    file, err := os.OpenFile(name, O_RDONLY, perm)  //只讀模式開啟檔案
    if err != nil {
        fmt.Printf("err:%v\n", err)
    } else {
        fmt.Printf("file:%v\n", file.Name())
    }
}
file.Close()關閉檔案
func (f *File) Close() error

在對檔案操作結束後我們需要檔案關閉,所以以經常和defer一起使用

例項:

func ReadFile(name){
  file, err := os.Open(name)
    if err != nil {
        fmt.Printf("err:%v\n", err)
        return
    }

  defer file.Close()

  //將檔案讀取到緩衝區
    buf := make([]byte, 100)
    n, err := file.Read(buf)
}
file.Read()讀取檔案
func (f *File) Read(b []byte) (n int, err error)

file.Read中需要一個byte型別的切片做緩衝區,並將檔案資料讀入這個緩衝區,然後返回讀取到的資料長度和error

例項:

//ReadFile 讀取檔案
func ReadFile(name string) {
  //開啟檔案
    file, err := os.Open(name)
    if err != nil {
        fmt.Printf("err:%v\n", err)
        return
    }
    for {
        //將檔案讀取到緩衝區
        buf := make([]byte, 5)  //設定一個緩衝區,一次讀取5個位元組
        n, err := file.Read(buf)
        fmt.Printf("buf:%v\n", string(buf))
        fmt.Printf("數字:%d\n", n)
        if err == io.EOF { //表示檔案讀取完畢
            break
        }
    }
    file.Close()
}
file.ReadAt從指定位置開始讀取
func (f *File) ReadAt(b []byte, off int64) (n int, err error)

例項:

//FileReadAt 從指定位置開始讀取
func FileReadAt(name string) {
    file, err := os.Open(name)
    if err != nil {
        fmt.Printf("err:%v\n", err)
    }

    buf := make([]byte, 10)       // 設定一個緩衝區,一次讀10個位元組
    n, err := file.ReadAt(buf, 5) //從第五個開始讀取
    fmt.Printf("buf:%v\n", string(buf))
    fmt.Printf("n:%s\n", n)

    file.Close()
}
file.ReadDir() 讀取目錄
func (f *File) ReadDir(n int) ([]DirEntry, error)

返回當前目錄下的所有目錄及檔案放入[]DirEntry

例項:

//ReadDir 獲取目錄
func ReadDir(name string) {
    file, err := os.Open(name)
    if err != nil {
        fmt.Printf("err:%v\n", err)
    }
    dir, err := file.ReadDir(-1)
    if err != nil {
        fmt.Printf("err:%v\n", err)
    }
    for key, value := range dir {
        fmt.Printf("dir:  key:%v, value: %v\n", key, value)
    }
}
設定偏移量
func (f *File) Seek(offset int64, whence int) (ret int64, err error)

例項:

func Seek(name string) {
    file, err := os.Open(name)   //開啟檔案游標預設為檔案開頭
    if err != nil {
        fmt.Println("err:", err)
    }
    buf := make([]byte, 5)
    file.Seek(3, 0) // 從索引值為3處開始讀
    n, err := file.Read(buf)
    if err != nil {
        fmt.Printf("err:%v\n", err)
    }
    fmt.Printf("info:%s\n", string(buf))
    fmt.Printf("n:%s\n", n)
    file.Close()
}
file.Stat()獲取檔案資訊
func (f *File) Stat() (FileInfo, error)

例項:

//StatFile 獲取檔案資訊
func StatFile(name string) {
    file, err := os.Open(name)
    if err != nil {
        fmt.Printf("err:%v\n", err)
    }
    fInfo, err := file.Stat()
    if err != nil {
        fmt.Printf("err:%v\n", err)
    }
    fmt.Printf("f是否是一個檔案: %v\n", fInfo.IsDir())
    fmt.Printf("f檔案的修改時間: %v\n", fInfo.ModTime().String())
    fmt.Printf("f檔案的名稱: %v\n", fInfo.Name())
    fmt.Printf("f檔案的大小: %v\n", fInfo.Size())
    fmt.Printf("f檔案的許可權: %v\n", fInfo.Mode().String())
}

檔案寫操作

file.Write()資料寫入
func (f *File) Write(b []byte) (n int, err error)

例項:

//WritFile 寫入資料
func WritFile(name string) {
    file, err := os.OpenFile(name, O_RDWR, 0775) // 以讀寫模式開啟檔案,並且開啟時清空檔案
    if err != nil {
        fmt.Printf("err:%v\n", err)
    }
    for i := 0; i < 10; i++ {
        file.Write([]byte(fmt.Sprintf("hello golang 我是%d\n  ", i)))
    }
    file.Close()
}

執行結果:

hello golang 我是0
hello golang 我是1
hello golang 我是2
hello golang 我是3
hello golang 我是4
hello golang 我是5
hello golang 我是6
hello golang 我是7
hello golang 我是8
hello golang 我是9
file.WriteString()寫入字串
func (f *File) WriteString(s string) (n int, err error

例項:

//WriteStringFile 寫入字串
func WriteStringFile(name string) {
    file, err := os.OpenFile(name, O_RDWR, 0775) // 以讀寫模式開啟檔案,並且開啟時清空檔案
    if err != nil {
        fmt.Printf("err:%v\n")
    }
    file.WriteString("您好 golang")
}
file.WriteAt()寫入指定位置
func (f *File) WriteAt(b []byte, off int64) (n int, err error)

例項:

//WriteFileAt 寫入指定位置
func WriteFileAt(name string) {
    file, err := os.OpenFile(name, O_RDWR, 0775) // 以讀寫模式開啟檔案,並且開啟時清空檔案
    if err != nil {
        fmt.Printf("err:%v\n")
    }
    file.WriteAt([]byte("學習使我快樂"), 10) // 從索引值為10的地方開始寫入並覆蓋原來當前位置的資料
}

例項:使用緩衝區

//WriteFile 使用緩衝區
func WriteFile(name string) {
    file, err := os.OpenFile(name, O_RDWR, 0775) // 以讀寫模式開啟檔案,並且開啟時清空檔案
    if err != nil {
        fmt.Printf("err:%v\n")
    }
    defer file.Close()

    //寫入檔案時,使用帶快取的 *Writer
    writefile := bufio.NewWriter(file)
    for i := 0; i < 50; i++ {
        writefile.WriteString(fmt.Sprintf("您好,我是第%d個帥哥  \n", i))
    }
    //Flush將快取的檔案真正寫入到檔案中
    writefile.Flush()
}
逐行讀取

os包沒有給我們提供逐行讀取的方法,這需要我們自己實現:

//ReadLine 逐行讀
func ReadLine(fileName string) error {
    f, err := os.Open(fileName)
    if err != nil {
        return err
    }
    //將檔案讀到緩衝區
    buf := bufio.NewReader(f)

    for {
        line, err := buf.ReadString('\n')
        line = strings.TrimSpace(line)
        fmt.Printf("行資料:%v\n", line)
        if err != nil {
            if err == io.EOF {
                return nil
            }
            return err
        }
    }
    return nil
}

程式相關

func Exit(code int) // 讓當前程式以給出的狀態碼(code)退出。一般來說,狀態碼0表示成功,非0表示出錯。程式會立刻終止,defer的函式不會被執行。

func Getuid() int // 獲取呼叫者的使用者id

func Geteuid() int // 獲取呼叫者的有效使用者id

func Getgid() int // 獲取呼叫者的組id

func Getegid() int // 獲取呼叫者的有效組id

func Getgroups() ([]int, error) // 獲取呼叫者所在的所有組的組id

func Getpid() int // 獲取呼叫者所在程式的程式id

func Getppid() int // 獲取呼叫者所在程式的父程式的程式id

環境相關

func Hostname() (name string, err error) // 獲取主機名

func Getenv(key string) string // 獲取某個環境變數

func Setenv(key, value string) error // 設定一個環境變數,失敗返回錯誤,經測試當前設定的環境變數只在 當前程式有效(當前程式衍生的所以的go程都可以拿到,子go程與父go程的環境變數可以互相獲取);程式退出消失

func Clearenv() // 刪除當前程式已有的所有環境變數。不會影響當前電腦系統的環境變數,這些環境變數都是對當前go程式而言的
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章