Go標(biāo)準(zhǔn)庫(kù)os
包提供了操縱操作系統(tǒng)的能力
對(duì)于文件和目錄的操作地熄,Go提供兩種類(lèi)型分別是os.File
結(jié)構(gòu)和os.FileInfo
接口励负。
type File struct {
*file // os specific
}
os.File
代表一個(gè)打開(kāi)的文件對(duì)象句柄崖叫,即文件描述符饺蔑。
os.File
類(lèi)型代表了操作系統(tǒng)中的文件,在UNIX操作系統(tǒng)中一切都是文件秋麸,比如文本文件渐排、二進(jìn)制文件、壓縮文件灸蟆、目錄驯耻、符號(hào)連接、物理設(shè)備炒考、命名管道可缚、套接字等。
os.File
類(lèi)型擁有的都是指針?lè)椒ㄆ毖羔槍?shí)現(xiàn)了很多io
包中的接口城看。對(duì)于io
包中最核心的三個(gè)接口io.Reader
、io.Writer
杏慰、io.Closer
测柠,*os.File
類(lèi)型都實(shí)現(xiàn)了。
os.File
類(lèi)型機(jī)器指針類(lèi)型的值缘滥,不但可以通過(guò)各種方式來(lái)讀寫(xiě)文件內(nèi)容轰胁,還可以尋找并設(shè)定下一次讀寫(xiě)的起始索引位置,此外還可以隨時(shí)對(duì)文件進(jìn)行關(guān)閉朝扼。
要操作文件就需要先獲取os.File
類(lèi)型的指針值赃阀,os
包提供了4個(gè)獲取指針值的函數(shù)。
函數(shù) | 返回 | 描述 |
---|---|---|
os.Create | *os.File | 覆蓋式創(chuàng)建 |
os.NewFile | *os.File | 創(chuàng)建文件 |
os.Open | *os.File | 打開(kāi)文件 |
os.OpenFile | *os.File | 打開(kāi)文件 |
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)
擎颖,以可讀寫(xiě)榛斯、可創(chuàng)建、內(nèi)容清空的方式創(chuàng)建指定名稱的文件搂捧。
文件標(biāo)志位 | 描述 |
---|---|
O_RDWR | 以讀寫(xiě)模式打開(kāi)文件 |
O_CREATE | 若文件不存在則創(chuàng)建全新文件 |
O_TRUNC | 若可能打開(kāi)時(shí)清空文件 |
-
os.Create()
會(huì)根據(jù)給定的路徑創(chuàng)建一個(gè)全新的文件驮俗,返回*os.File
和錯(cuò)誤值。通過(guò)返回值*os.File
可以對(duì)相應(yīng)文件進(jìn)行讀寫(xiě)操作允跑。 - 使用
os.Create()
創(chuàng)建的文件王凑,對(duì)操作系統(tǒng)中所有用戶都是可讀寫(xiě)的。 -
os.Create()
采用0666(任何人都可讀可寫(xiě)不可執(zhí)行)權(quán)限模式來(lái)創(chuàng)建文件
文件路徑
- 若給定路徑的文件已存在聋丝,則會(huì)先清空現(xiàn)有文件中的內(nèi)容索烹,再將文件的
*os.File
返回。 - 若路徑不存在則會(huì)返回一個(gè)
*os.PathError
類(lèi)型的錯(cuò)誤值弱睦。
創(chuàng)建結(jié)果
- 創(chuàng)建成功百姓,會(huì)返回文件對(duì)象用于I/O操作,對(duì)應(yīng)的文件描述符具有
O_RDWR
模式况木。 - 創(chuàng)建失敗瓣戚,錯(cuò)誤原因可能是路徑不存在端圈、權(quán)限不足、打開(kāi)文件數(shù)量超過(guò)上限子库、磁盤(pán)空間不足等舱权,錯(cuò)誤底層類(lèi)型為
*PathError
。
例如:創(chuàng)建一個(gè)文件
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)
文件打開(kāi)
os.Open
os.Open
會(huì)打開(kāi)一個(gè)文件用來(lái)讀取
- 若打開(kāi)成功則會(huì)返回文件對(duì)象,對(duì)應(yīng)的文件描述符具有
O_RDONLY
只讀模式,使用返回的文件對(duì)象可用于讀取數(shù)據(jù)宇色。 - 若打開(kāi)出錯(cuò),返回的錯(cuò)誤對(duì)象底層類(lèi)型為
*PathError
鸵贬。
func Open(name string) (*File, error) {
return OpenFile(name, O_RDONLY, 0)
}
os.OpenFile
-
os.OpenFile
是相對(duì)底層的文件打開(kāi)函數(shù),使用時(shí)建議優(yōu)先采用os.Open
或os.Create
脖捻。 -
os.OpenFile
支持使用指定模式和權(quán)限打開(kāi)文件阔逼,打開(kāi)成功則返回文件描述符可用于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)前路徑下運(yùn)行則需添加具體路徑嗜浮。 |
flag | 打開(kāi)標(biāo)記/打開(kāi)方式/文件處理參數(shù) |
perm | 權(quán)限控制,Windows無(wú)效摩疑。 |
打開(kāi)標(biāo)記 flag
打開(kāi)標(biāo)記 | 描述 |
---|---|
O_RDONLY | 以只讀模式打開(kāi)文件 |
O_WRONLY | 以只寫(xiě)模式打開(kāi)文件 |
O_RDWR | 以讀寫(xiě)模式打開(kāi)文件 |
O_APPEND | 以追加模式打開(kāi)文件危融,即寫(xiě)操作時(shí)將數(shù)據(jù)附加到文件末尾。 |
O_CREATE | 若文件不存在則創(chuàng)建 |
O_EXCL | 與O_CREATE配合用于新建文件雷袋,文件必須不存在有效吉殃,若文件存在則出錯(cuò)。 |
O_SYNC | 以同步方式打開(kāi)楷怒,不使用緩存直接寫(xiě)入磁盤(pán)蛋勺,在一系列寫(xiě)操作時(shí)每次都要等待上次I/O操作完成后才能再繼續(xù)。 |
O_TRUNC | 打開(kāi)時(shí)清空文件 |
打開(kāi)標(biāo)記 | 描述 |
---|---|
os.O_WRONLY|os.O_CREATE|os.O_EXCL |
若文件已存在則打開(kāi)失敗 |
os.O_WRONLY|os.O_CREATE |
若文件已存在則覆蓋式寫(xiě)入鸠删,不會(huì)清空原文件迫卢,而是從頭直接覆蓋寫(xiě)入。 |
os.O_WRONLY|os.O_CREATE|os.O_APPEND |
若文件已存在則向尾部添加來(lái)寫(xiě)入 |
權(quán)限控制 perm
os.FileMode
代表文件模式和權(quán)限位冶共,不同字位在所有操作系統(tǒng)中都具有相同的含義,因此文件信息可以在不同操作系統(tǒng)之間安全移植每界。但并不是所有位都能用于所有的操作系統(tǒng)捅僵,唯一共有的是用于表示目錄的ModeDir
位。
文件權(quán)限 | 描述 |
---|---|
os.ModeDir | 文件夾模式 |
os.ModeAppend | 追加模式 |
os.ModeExclusive | 單獨(dú)使用 |
os.ModeTemporary | 臨時(shí)文件 |
os.ModeSymlink | 象征性的關(guān)聯(lián) |
os.ModeDevice | 設(shè)備文件 |
os.NamePipe | 命令管道 |
os.ModeSocket | UNIX主機(jī)套接字 |
os.ModeSetuid | 設(shè)置uid |
os.ModeSetgid | 設(shè)置gid |
os.ModeCharDevice | UNIX字符設(shè)備眨层,當(dāng)設(shè)備模式為set 時(shí)庙楚。 |
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)
}
例如:同時(shí)創(chuàng)建多級(jí)目錄和其下的文件
//同時(shí)創(chuàng)建多級(jí)目錄及其下文件
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)閉文件描述符,使文件不能讀寫(xiě)趴樱。
func (f *File) Close() error {
if f == nil {
return ErrInvalid
}
return f.file.close()
}
文件存在
os.IsNotExist
os.IsNotExists()
接收一個(gè)錯(cuò)誤對(duì)象來(lái)判斷一個(gè)文件或目錄是否不存在馒闷,最終返回布爾值酪捡。
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()
接收一個(gè)錯(cuò)誤對(duì)象來(lái)判斷一個(gè)文件或目錄是否存在,最終返回布爾值纳账。
func IsExist(err error) bool
例如:判斷文件是否存在
//判斷文件是否存在
func FileExists(file string) bool {
if _,err := os.Stat(file); os.IsExist(err) {
return true
}
return false
}