#### Go 文件操做
文件在程序是以流的形式操做的, 在Python,JAVA,Go ... 都同樣;
流: 數據在數據源和程序之間通過的路徑
輸入流: 數據從數據源到程序的路徑
輸出流: 數據從程序到數據源的路徑
下面來學習一下在Go中如何操做文件;
os.File 封裝了全部文件相關的操做,File 是一個結構體,有不少方法
##### 打開和關閉文件
package main import ( "fmt" "os" ) func main(){ // 打開文件 // 默認返回兩個值 // 第一個爲file 對象,也可稱爲file 指針 // 第二個爲錯誤信息,若是有錯誤,則err != nil file,err := os.Open("./test.txt") if err != nil { fmt.Println("open file error") fmt.Println(err) return } // 正常狀況下打開文件後,file 其實是一個指針,類型爲*File fmt.Printf("file=%v",file) // 正常操做完文件後須要手動關閉文件,避免內存泄漏 err = file.Close() if err != nil { fmt.Println("close file error") } }
##### 讀取文件
package main import ( "bufio" "fmt" "io" "io/ioutil" "os" ) func main(){ // 打開文件 // 默認返回兩個值 // 第一個爲file 對象,也可稱爲file 指針 // 第二個爲錯誤信息,若是有錯誤,則err != nil file,err := os.Open("./test.txt") if err != nil { fmt.Println("open file error") fmt.Println(err) return } // 正常狀況下打開文件後,file 其實是一個指針,類型爲*File fmt.Printf("file=%v\n",file) // 正常操做完文件後須要手動關閉文件,避免內存泄漏 defer file.Close() // 第一種方式: 帶緩衝方式讀取文件 reader := bufio.NewReader(file) //var content []byte for { //1. 一行一行讀取 str,err := reader.ReadString('\n') //2. 帶緩衝讀取 //buf := make([]byte,1024) //n,err := reader.Read(buf) //content = append(content,buf[:n]...) if err == io.EOF { break } fmt.Print(str) } fmt.Println("file read end...") // 第二種方式: 一次性讀取全部文件內容 // 適用於文件內容不大的狀況 // ioutil.ReadFile 返回兩個值,一個是讀取到的內容字節切片, // 一個是返回的錯誤信息 content,err := ioutil.ReadFile("test.txt") if err != nil { fmt.Println(err) return } fmt.Println(string(content)) // ioutil.ReadFile 不須要顯示的close 文件, open 和 close 方法被封裝在ReadFile 內部 }
##### 寫文件
關於打開文件指定選擇,能夠自行測試,特別是O_APPEND,O_TRUNC 使用較多;
package main import ( "bufio" "fmt" "os" ) func main(){ // os.OpenFile 是一個更爲通用的函數,它須要三個參數, // 1. 文件路徑 // 2. 指定選項,如下選項可組合使用 //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 // 若是可能,打開文件時清空文件 // 3. 文件模式 // linux r=4,w=2,x=1 file,err := os.OpenFile("./abc.txt",os.O_WRONLY| os.O_CREATE,0666) if err != nil { fmt.Println("file open error") return } defer file.Close() writer := bufio.NewWriter(file) for i := 0;i<5;i++{ writer.WriteString("hello,golang\n") } // bufio.NewWriter 是帶緩衝的寫,若是不調用Flush 方法, 那麼數據不會寫入文件 writer.Flush() }
##### 判斷文件是否存在
Go 中判斷文件或文件夾是否存在的方法爲使用os.Stat() 函數返回的錯誤值進行判斷
1. 若是返回的錯誤爲nil ,說明文件或文件夾存在
2. 若是返回的錯誤類型使用os.IsNotExist() 判斷爲true, 說明文件或文件夾不存在
3. 若是返回的錯誤爲其它類型, 則不肯定是否存在
func PathExists(path string)(bool,error) { _,err := os.Stat(path) if err != nil { if os.IsNotExist(err) { return false,nil } return false,err } return true,nil }
##### 文件複製
package main import ( "bufio" "fmt" "io" "os" ) func copyFile(srcFileName,destFileName string)(int64,error){ srcFile,err := os.Open(srcFileName) if err != nil { return 0,err } defer srcFile.Close() reader := bufio.NewReader(srcFile) destFile,err := os.OpenFile(destFileName,os.O_CREATE|os.O_WRONLY,0666) if err != nil { return 0,err } writer := bufio.NewWriter(destFile) defer destFile.Close() n,err := io.Copy(writer,reader) // 若是不調用 Flush 將會出現目標文件沒有內容 writer.Flush() return n,err } func main(){ _,err := copyFile("./a.jpg","./b.jpg") if err != nil { fmt.Println("copy file error") fmt.Println(err) return } fmt.Println("file copy finish") }
最新文章會在我的微信公衆號上同步更新,歡迎關注,你們一同交流學習 linux