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.Reader、io.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.Open或os.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
}