一扑眉、os包內(nèi)容介紹
* 使用os包中內(nèi)容進(jìn)行操作系統(tǒng)文件或目錄
* File結(jié)構(gòu)體表示操作系統(tǒng)文件(夾)
* 操作系統(tǒng)的文件都是有權(quán)限控制的,包含可讀,可寫等,在os包中FileMode表示文件權(quán)限,本質(zhì)是uint32,可取值都以常量形式提供
* FIleInfo是一個(gè)interface表示文件的信息
* 在獲取系統(tǒng)資源時(shí)資源路徑分為相對(duì)路徑和絕對(duì)路徑
* 相對(duì)路徑:在Go語言中相對(duì)路徑用于是GOPATH,也就是項(xiàng)目的根目錄
* 絕對(duì)路徑:磁盤根目錄開始表示資源詳細(xì)路徑的描述
* 創(chuàng)建文件夾
????/*
????如果文件夾已經(jīng)存在,不報(bào)錯(cuò),保留原文件夾
????如果父目錄不存在幫助創(chuàng)建
???? */
????error := os.MkdirAll("D:/godir/a/b", os.ModeDir)
????if error != nil {
????????fmt.Println("文件夾創(chuàng)建失敗",error)
????????return
????}
????fmt.Println("文件夾創(chuàng)建成功")
* 創(chuàng)建空文件
????/*
????創(chuàng)建文件時(shí)要求文件目錄必須已經(jīng)存在
????如果文件已經(jīng)存在則會(huì)創(chuàng)建一個(gè)空文件覆蓋之前的文件
???? */
????file, err := os.Create("D:/godir/test.txt")
????if err != nil {
????????fmt.Println("文件創(chuàng)建失敗,", err)
????????return
????}
????fmt.Println("文件創(chuàng)建成功",file.Name())
* 重命名文件或文件夾
????/*
????第一個(gè)參數(shù):原文件夾名稱,要求此路徑是必須存在的
????第二個(gè)參數(shù):新文件夾名稱
???? */
????err := os.Rename("D:/godir", "D:/godir1")
????if err != nil {
????????fmt.Println("重命名文件夾失敗,", err)
????????return
????}
????fmt.Println("文件夾重命名成功")
????/*
????重命名文件和重命名文件夾用法相同
???? */
????err = os.Rename("D:/godir1/test.txt", "D:/godir1/test1.txt")
????if err != nil {
????????fmt.Println("重命名文件失敗,", err)
????????return
????}
????fmt.Println("文件重命名成功")
* 獲取文件(夾)信息
????f, err := os.Open("D:/godir1/test1.txt")
????defer f.Close() //文件打開后要關(guān)閉,釋放資源
????if err != nil {
????????fmt.Println("打開文件失敗", err)
????????return
????}
????fileInfo, err := f.Stat()
????if err != nil {
????????fmt.Println("獲取文件信息失敗", err)
????????return
????}
????fmt.Println(fileInfo.Name())????//文件名
????fmt.Println(fileInfo.IsDir())???//是否是文件夾,返回bool,true表示文件夾,false表示文件
????fmt.Println(fileInfo.Mode())????//文件權(quán)限
????fmt.Println(fileInfo.ModTime()) //修改時(shí)間
????fmt.Println(fileInfo.Size())????//文件大小
* 刪除文件或文件夾
????/*
????只要文件夾存在,刪除文件夾.
????無論文件夾是否有內(nèi)容都會(huì)刪除
????如果刪除目標(biāo)是文件,則刪除文件
???? */
????err := os.RemoveAll("D:/godir1/a.txt")
????if err != nil {
????????fmt.Println("刪除失敗", err)
????????return
????}
????fmt.Println("刪除成功")
二个初、輸入流
* 流(stream)是應(yīng)用程序和外部資源進(jìn)行數(shù)據(jù)交互的紐帶
* 流分為輸入流和輸出流,輸入和輸出都是相對(duì)于程序,把外部數(shù)據(jù)傳入到程序中叫做輸入,反之叫做輸出流
* 輸入流(Input Stream)和輸出流(Output Stream)?就是平時(shí)所說的I/O流
* 在Go語言標(biāo)準(zhǔn)庫中io包下的Reader接口表示輸入流,只要實(shí)現(xiàn)這個(gè)接口就屬于輸入流
* 可以使用strings包下的NewReader創(chuàng)建字符串流
????r := strings.NewReader("hello 世界")
????b := make([]byte, r.Size())//創(chuàng)建字節(jié)切片,存放流中數(shù)據(jù),根據(jù)流數(shù)據(jù)大小創(chuàng)建切片大小
????n, err := r.Read(b)//把流中數(shù)據(jù)讀取到切片中
????if err != nil {
????????fmt.Println("讀取失敗,", err)
????????return
????}
????fmt.Println("讀取數(shù)據(jù)長度,", n)
????fmt.Println("流中數(shù)據(jù)",string(b))//以字符串形式輸入切片中數(shù)據(jù)
* 最常用的是文件流,把外部文件中數(shù)據(jù)讀取到程序中
????f, err := os.Open("D:/go.txt")//打開文件
????defer f.Close()
????if err != nil {
????????fmt.Println("文件讀取失敗,", err)
????????return
????}
????fileInfo, err := f.Stat()//獲取文件信息
????if err != nil {
????????fmt.Println("文件信息獲取失敗,", err)
????????return
????}
????b := make([]byte, fileInfo.Size())//根據(jù)文件中數(shù)據(jù)大小創(chuàng)建切片
????_, err = f.Read(b)//讀取數(shù)據(jù)到切片中
????if err != nil {
????????fmt.Println("文件流讀取失敗:", err)
????????return
????}
????fmt.Println("文件中內(nèi)容為:", string(b))//以字符串形式輸入切片中數(shù)據(jù)
三硝枉、輸出流
* 輸出流就是把程序中數(shù)據(jù)寫出到外部資源
* Go語言標(biāo)準(zhǔn)庫中輸出流是Writer接口
* 注意:輸出流時(shí)不要使用os.Open()抚笔,因?yàn)檫@種方式獲取的文件是只讀的
????fp := "D:/go.txt"
????/*
????第三個(gè)參數(shù)表示文件權(quán)限
????第 1 位在權(quán)限中總是為 0
????第 2 位為 0 表示文件不可以被讀, 為 1 表示可以被讀
????第 3 位為 0 表示文件不可以被寫衰倦, 為 1 表示可以被寫
????第 4 位為 0 表示文件不可以被執(zhí)行花鹅, 為 1 表示可以被執(zhí)行
????整理如下:
???????0(0000): 不可讀寫,不能被執(zhí)行
???????1(0001): 不可讀寫,能被執(zhí)行
???????2(0010): 可寫不可讀,不能被執(zhí)行
???????3(0011): 可寫不可讀,能被執(zhí)行
???????4(0100): 可讀不可寫,不能被執(zhí)行
???????5(0101): 可讀不可寫,能被執(zhí)行
???????6(0110): 可讀寫,不能執(zhí)行
???????7(0111): 可讀寫,可執(zhí)行
????0666:
????第一個(gè) 0 表示這個(gè)數(shù)是 八進(jìn)制
????第一個(gè) 6 表示文件擁有者有讀寫權(quán)限,但沒有執(zhí)行權(quán)限
????第二個(gè) 6 表示文件擁有者同組用戶有讀寫權(quán)限交掏,但沒有執(zhí)行權(quán)限
????第三個(gè) 6 表示其它用戶有讀寫權(quán)限妆偏,但沒有執(zhí)行權(quán)限
???? */
????//第二個(gè)參數(shù)表示文件內(nèi)容追加
????//第三個(gè)參數(shù)表示創(chuàng)建文件時(shí)文件權(quán)限
????f, err := os.OpenFile(fp, os.O_APPEND, 0660)
????defer f.Close()
????if err != nil {
????????fmt.Println("文件不存在,創(chuàng)建文件")
????????f, _ = os.Create(fp)
????}
????/*
????內(nèi)容中識(shí)別特殊字符
????\r\n 換行
????\t 縮進(jìn)
???? */
? ? // 使用文件對(duì)象重寫的Writer接口,參數(shù)是[]byte
????f.Write([]byte("使用Writer接口寫數(shù)據(jù)\r\n"))
? ? // 使用WriteString接口的方法,參數(shù)是字符串,使用更方便
????f.WriteString("寫了\t一段\r\n內(nèi)容123")
????fmt.Println("程序執(zhí)行結(jié)束")
四、ioutil包
* ioutil包下提供了對(duì)文件讀寫的工具函數(shù),通過這些函數(shù)快速實(shí)現(xiàn)文件的讀寫操作
* ioutil包下提供的函數(shù)比較少,但是都是很方便使用的函數(shù)
?? ?func NopCloser(r io.Reader) io.ReadCloser
?? ?func ReadAll(r io.Reader) ([]byte, error)
?? ?func ReadFile(filename string) ([]byte, error)
?? ?func WriteFile(filename string, data []byte, perm os.FileMode) error
?? ?func ReadDir(dirname string) ([]os.FileInfo, error)
?? ?func TempDir(dir, prefix string) (name string, err error)
?? ?func TempFile(dir, prefix string) (f *os.File, err error)
* 打開完文件后可以使用ReadAll把文件中所有內(nèi)容都讀取到
????f, err := os.Open("D:/go.txt")
????defer f.Close()
????if err != nil {
????????fmt.Println(err)
????????return
????}
????b, err := ioutil.ReadAll(f)
????if err != nil {
????????fmt.Println(err)
????????return
????}
????fmt.Println("文件中內(nèi)容:\n", string(b))
* 也可以直接讀取文件中內(nèi)容
?? ?b, err := ioutil.ReadFile("D:/go.txt")
????if err != nil {
????????fmt.Println(err)
????????return
????}
????fmt.Println(string(b))
* 寫文件也很簡(jiǎn)單,直接使用WriteFile函數(shù)即可,但是源碼中已經(jīng)規(guī)定此文件只能是可寫狀態(tài),且不是尾加數(shù)據(jù)
????err := ioutil.WriteFile("D:/abc.txt", []byte("內(nèi)容123123"), 0666)
????if err != nil {
????????fmt.Println(err)
????????return
????}
????fmt.Println("數(shù)據(jù)寫入成功")
* 還提供了快速獲取某個(gè)文件夾中所有文件信息的函數(shù)
????fs,_:=ioutil.ReadDir("D:/")
????for _,n := range fs {
????????fmt.Println(n.Name())
????}