os.File

Go標(biāo)準(zhǔn)庫os包提供了操縱操作系統(tǒng)的能力

對于文件和目錄的操作,Go提供兩種類型分別是os.File結(jié)構(gòu)和os.FileInfo接口。

type File struct {
    *file // os specific
}

os.File代表一個打開的文件對象句柄,即文件描述符。

os.File類型代表了操作系統(tǒng)中的文件,在UNIX操作系統(tǒng)中一切都是文件,比如文本文件、二進制文件、壓縮文件、目錄、符號連接、物理設(shè)備、命名管道、套接字等。

os.File類型擁有的都是指針方法,指針實現(xiàn)了很多io包中的接口。對于io包中最核心的三個接口io.Readerio.Writer、io.Closer*os.File類型都實現(xiàn)了。

os.File類型機器指針類型的值,不但可以通過各種方式來讀寫文件內(nèi)容,還可以尋找并設(shè)定下一次讀寫的起始索引位置,此外還可以隨時對文件進行關(guān)閉。

要操作文件就需要先獲取os.File類型的指針值,os包提供了4個獲取指針值的函數(shù)。

函數(shù) 返回 描述
os.Create *os.File 覆蓋式創(chuàng)建
os.NewFile *os.File 創(chuàng)建文件
os.Open *os.File 打開文件
os.OpenFile *os.File 打開文件

os.Create

func Create(name string) (*File, error) {
    return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
}

os.Create()的函數(shù)原型是OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666),以可讀寫、可創(chuàng)建、內(nèi)容清空的方式創(chuàng)建指定名稱的文件。

文件標(biāo)志位 描述
O_RDWR 以讀寫模式打開文件
O_CREATE 若文件不存在則創(chuàng)建全新文件
O_TRUNC 若可能打開時清空文件
  • os.Create()會根據(jù)給定的路徑創(chuàng)建一個全新的文件,返回*os.File和錯誤值。通過返回值*os.File可以對相應(yīng)文件進行讀寫操作。
  • 使用os.Create()創(chuàng)建的文件,對操作系統(tǒng)中所有用戶都是可讀寫的。
  • os.Create()采用0666(任何人都可讀可寫不可執(zhí)行)權(quán)限模式來創(chuàng)建文件

文件路徑

  • 若給定路徑的文件已存在,則會先清空現(xiàn)有文件中的內(nèi)容,再將文件的*os.File返回。
  • 若路徑不存在則會返回一個*os.PathError類型的錯誤值。

創(chuàng)建結(jié)果

  • 創(chuàng)建成功,會返回文件對象用于I/O操作,對應(yīng)的文件描述符具有O_RDWR模式。
  • 創(chuàng)建失敗,錯誤原因可能是路徑不存在、權(quán)限不足、打開文件數(shù)量超過上限、磁盤空間不足等,錯誤底層類型為*PathError。

例如:創(chuàng)建一個文件

tmpdir := os.TempDir()
filename := filepath.Join(tmpdir, "test.log")

file, err := os.Create(filename)
defer file.Close()
if err != nil {
    log.Fatalln(err)
}
fmt.Printf("%+v\n", file) //&{file:0xc00011e780}

file.WriteString("hello world")

buf, err := os.ReadFile(filename)
if err != nil {
    log.Fatalln(err)
}
fmt.Printf("%s\n", buf) //hello world

defer os.Remove(filename)

文件打開

os.Open

os.Open會打開一個文件用來讀取

  • 若打開成功則會返回文件對象,對應(yīng)的文件描述符具有O_RDONLY只讀模式,使用返回的文件對象可用于讀取數(shù)據(jù)。
  • 若打開出錯,返回的錯誤對象底層類型為*PathError
func Open(name string) (*File, error) {
    return OpenFile(name, O_RDONLY, 0)
}

os.OpenFile

  • os.OpenFile是相對底層的文件打開函數(shù),使用時建議優(yōu)先采用os.Openos.Create
  • os.OpenFile支持使用指定模式和權(quán)限打開文件,打開成功則返回文件描述符可用于I/O,
func OpenFile(name string, flag int, perm FileMode) (*File, error) {
    testlog.Open(name)
    f, err := openFileNolog(name, flag, perm)
    if err != nil {
        return nil, err
    }
    f.appendMode = flag&O_APPEND != 0

    return f, nil
}
參數(shù) 描述
name 文件名稱,若不在當(dāng)前路徑下運行則需添加具體路徑。
flag 打開標(biāo)記/打開方式/文件處理參數(shù)
perm 權(quán)限控制,Windows無效。

打開標(biāo)記 flag

打開標(biāo)記 描述
O_RDONLY 以只讀模式打開文件
O_WRONLY 以只寫模式打開文件
O_RDWR 以讀寫模式打開文件
O_APPEND 以追加模式打開文件,即寫操作時將數(shù)據(jù)附加到文件末尾。
O_CREATE 若文件不存在則創(chuàng)建
O_EXCL 與O_CREATE配合用于新建文件,文件必須不存在有效,若文件存在則出錯。
O_SYNC 以同步方式打開,不使用緩存直接寫入磁盤,在一系列寫操作時每次都要等待上次I/O操作完成后才能再繼續(xù)。
O_TRUNC 打開時清空文件
打開標(biāo)記 描述
os.O_WRONLY|os.O_CREATE|os.O_EXCL 若文件已存在則打開失敗
os.O_WRONLY|os.O_CREATE 若文件已存在則覆蓋式寫入,不會清空原文件,而是從頭直接覆蓋寫入。
os.O_WRONLY|os.O_CREATE|os.O_APPEND 若文件已存在則向尾部添加來寫入

權(quán)限控制 perm

os.FileMode代表文件模式和權(quán)限位,不同字位在所有操作系統(tǒng)中都具有相同的含義,因此文件信息可以在不同操作系統(tǒng)之間安全移植。但并不是所有位都能用于所有的操作系統(tǒng),唯一共有的是用于表示目錄的ModeDir位。

文件權(quán)限 描述
os.ModeDir 文件夾模式
os.ModeAppend 追加模式
os.ModeExclusive 單獨使用
os.ModeTemporary 臨時文件
os.ModeSymlink 象征性的關(guān)聯(lián)
os.ModeDevice 設(shè)備文件
os.NamePipe 命令管道
os.ModeSocket UNIX主機套接字
os.ModeSetuid 設(shè)置uid
os.ModeSetgid 設(shè)置gid
os.ModeCharDevice UNIX字符設(shè)備,當(dāng)設(shè)備模式為set時。
os.ModeSticky 粘性模式
os.Irregular 非常規(guī)模式
os.ModeType 比特位覆蓋
os.ModePerm 權(quán)限位

例如:創(chuàng)建文件并追加內(nèi)容

//創(chuàng)建文件并追加內(nèi)容
func FileAppend(name string, content string) (int, error){
    f,err := os.OpenFile(name, os.O_CREATE|os.O_RDWR|os.O_APPEND, os.ModeAppend | os.ModePerm)
    if err!=nil {
        return 0,err
    }
    defer f.Close()

    n,err := f.WriteString(content)
    if err!=nil{
        return 0, err
    }
    return n, nil
}
func main(){
    n,err := FileAppend("file.txt", "hello world")
    if err!=nil {
        fmt.Println(err)
        return
    }
    fmt.Println(n)
}

例如:同時創(chuàng)建多級目錄和其下的文件

//同時創(chuàng)建多級目錄及其下文件
func Mkfile(dirpath string, filename string, content string) error {
    err := os.MkdirAll(dirpath, os.ModePerm)
    log.Println(1, err)
    if err!=nil {
        return err
    }

    filename = path.Join(dirpath, filename)
    f,err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
    log.Println(2, err)
    defer f.Close()
    if err!=nil {
        return err
    }

    _,err = f.WriteString(content)
    log.Println(3, err)
    if err!=nil {
        return err
    }

    return nil
}

關(guān)閉文件 os.Close

os.Close()用于關(guān)閉文件描述符,使文件不能讀寫。

func (f *File) Close() error {
    if f == nil {
        return ErrInvalid
    }
    return f.file.close()
}

文件存在

os.IsNotExist

os.IsNotExists()接收一個錯誤對象來判斷一個文件或目錄是否不存在,最終返回布爾值。

func IsNotExist(err error) bool

例如:判斷文件是否存在

//判斷文件是否存在
func FileExists(file string) bool {
    _,err := os.Stat(file)
    if os.IsNotExist(err) {
        return false
    }
    return true
}

os.IsExist

os.IsExists()接收一個錯誤對象來判斷一個文件或目錄是否存在,最終返回布爾值。

func IsExist(err error) bool

例如:判斷文件是否存在

//判斷文件是否存在
func FileExists(file string) bool {
    if _,err := os.Stat(file); os.IsExist(err) {
        return true
    }
    return false
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容