<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
檔案是資料來源(儲存資料的地方)的一種,檔案最主要的作用就是儲存資料。
檔案在程式中是以流的形式來操作的。
開啟檔案:
func Open(filename string) (file *File, err error)
Open開啟一個檔案用於讀取。如果操作成功,返回的檔案物件的方法可用於讀取資料;對應的檔案描述符具有O_RDONLY
模式。如果出錯,錯誤底層型別是*PathError
。
關閉檔案:
func (f *File) Close() error
Close關閉檔案f,使檔案不能用於讀寫。它返回可能出現的錯誤。
範例:
package main import ( "fmt" "os" ) func main() { //唯讀方式開啟當前目錄下的test.txt file, err := os.Open("test.txt") if err != nil { fmt.Println("open file failed!,err:",err) } //返回的是一個指標 fmt.Println(&file) //關閉檔案 //err = file.Close() //if err != nil{ // fmt.Println("close file failed!,err:",err) //} //為了防止檔案忘記關閉,通常使用defer註冊檔案關閉語句。 defer file.Close() // 關閉檔案 }
執行結果:
0xc0000ce018
defer
—般用於資源的釋放和異常的捕捉。defer
語句會將其後面跟隨的語句進行延遲處理
;跟在defer
後面的語言將會在程式進行最後的return
之後再執行。defer
歸屬的函數即將返回時,將延遲處理的語句按defer
的逆序進行執行,也就是說,先被defer
的語句最後被執行,最後被 defer
的語句,最先被執行。func (f *File) Read(b []byte) (n int, err error)
從檔案物件中讀取長度為b的位元組,返回當前讀到的位元組數以及錯誤資訊。因此使用該方法需要先初始化一個符合內容大小的空的位元組列表。讀取到檔案的末尾時,該方法返回0,io.EOF
。
func (file *File) ReadAt(b []byte, off int64) (n int, err Error)
從檔案的off偏移量開始讀取長度為b的位元組。返回讀取到位元組數以及錯誤資訊。當讀取到的位元組數n小於想要讀取位元組的長度len(b)
的時候,該方法將返回非空的error。當讀到檔案末尾時,err返回io.EOF。
注意:ReadAt 絕對不允許出現,沒有讀滿 buffer,又非 EOF,又沒有 err 的情況發生,這個是介面語意明確規定的,這是一個非常細節的區別。
適用於讀取較小檔案使用:
package main import ( "fmt" "io" "os" ) func main() { //1、唯讀方式開啟當前目錄下的test2.txt file, err := os.Open("test2.txt") if err != nil { fmt.Println("open file failed!,err:",err) return } //3、當函數退出時,及時關閉file //使用 defer 內建函數 當函數退出時才會呼叫,要及時關閉否則會記憶體洩露 defer file.Close() //2、使用Read方法讀取資料,注意一次只會讀取128個位元組 tmp := make([]byte, 128) n, err := file.Read(tmp) //使用ReadAt方法讀取資料,注意一次只會讀取6個位元組 //tmp := make([]byte, 6) //n, err := file.ReadAt(tmp,6) //io.EOF 表示檔案的末尾 if err == io.EOF { fmt.Println("檔案讀取完畢") return } if err != nil { fmt.Println("read file failed,err:",err) return } fmt.Printf("讀取了 %d 位元組資料n", n) fmt.Println(string(tmp[:n])) }
執行結果:
讀取了 13 位元組資料
Hello Golang!
使用 for 迴圈讀取檔案中的所有資料:
package main import ( "fmt" "io" "os" ) //迴圈讀取檔案 func main() { //唯讀方式開啟當前目錄下的test.txt file, err := os.Open("test.txt") if err != nil { fmt.Println("open file failed!,err:",err) return } //關閉檔案 defer file.Close() //迴圈讀取檔案 var content []byte //使用Read方法讀取資料,注意一次只會讀取128個位元組 tmp := make([]byte, 128) for { n, err := file.Read(tmp) //每次讀取128個位元組 if err == io.EOF { fmt.Println("檔案讀取完畢") break } if err != nil { fmt.Println("read file failed,err:",err) return } //每次讀取的內容都追加到已知的byte切片中 content = append(content,tmp[:n]...) } //將byte型別轉換結果,列印結果 fmt.Println(string(content)) }
執行結果:
檔案讀取完畢
水陸草木之花,可愛者甚蕃。晉陶淵明獨愛菊。自李唐來,世人甚愛牡丹。
予獨愛蓮之出淤泥而不染,濯清漣而不妖,中通外直,不蔓不枝,香遠益清,亭亭淨植,可遠觀而不可褻玩焉。予謂菊,花之隱逸者也;牡丹,花之富貴者也;蓮,花之君子者也。
噫!菊之愛,陶後鮮有聞。蓮之愛,同予者何人?牡丹之愛,宜乎眾矣!
說明:
這裡的迴圈讀取檔案其實就是一個不斷追加的過程,將每次讀取的128個位元組追加到預先定義好的content切片中,最後將切片轉換成string型別,進行列印顯示。
語法:
//bufio.NewReader(rd io.Reader) *Reader r := bufio.NewReader(file) //func (b *Reader) ReadString(delim byte) (string, error) n, err := r.Read(buf)
引數
返回值:
使用 NewReader 讀取檔案時,首先,需要開啟檔案,接著, 使用開啟的檔案返回的檔案控制程式碼當作 函數引數 傳入 NewReader。
最後,使用 NewReader 返回的 reader 物件呼叫 Read 來讀取檔案。檔案讀取結束的標誌是返回的 n 等於 0,因此,如果需要讀取整個檔案內容,那麼我們需要使用 for 迴圈 不停的讀取檔案,直到 n 等於 0。
範例:
package main import ( "bufio" "fmt" "io" "os" ) //bufio讀取檔案 func main() { //唯讀方式開啟當前目錄下的test.txt file, err := os.Open("test.txt") if err != nil { fmt.Println("open file failed!,err:",err) return } //關閉檔案,避免記憶體洩露 defer file.Close() //通過bufio緩衝區讀取檔案 reader := bufio.NewReader(file) //建立緩衝區,將檔案內容放入到緩衝區 //迴圈讀取檔案資訊 for { line, err := reader.ReadString('n') //讀到一個換行就結束 if err == io.EOF { //io.EOF 表示檔案的末尾 //輸出最後的內容 if len(line) != 0 { fmt.Println(line) } fmt.Println("檔案讀取完畢") break } if err != nil { fmt.Println("read file failed,err:",err) return } fmt.Println(line) } }
執行結果:
水陸草木之花,可愛者甚蕃。晉陶淵明獨愛菊。自李唐來,世人甚愛牡丹。
予獨愛蓮之出淤泥而不染,濯清漣而不妖,中通外直,不蔓不枝,香遠益清,亭亭淨植,可遠觀而不可褻玩焉。
予謂菊,花之隱逸者也;牡丹,花之富貴者也;蓮,花之君子者也。
噫!菊之愛,陶後鮮有聞。蓮之愛,同予者何人?牡丹之愛,宜乎眾矣!
檔案讀取完畢
語法:
func ReadFile(name string) ([]byte, error)
使用 io/ioutil.ReadFile
方法一次性將檔案讀取到記憶體中,只需要將檔名作為引數傳入。
範例:
package main import ( "fmt" "io/ioutil" ) //ioutil 讀取整個檔案 func main() { content, err := ioutil.ReadFile("test.txt") if err != nil { fmt.Println("read failed,err:",err) return } fmt.Println(string(content)) }
執行結果:
水陸草木之花,可愛者甚蕃。晉陶淵明獨愛菊。自李唐來,世人甚愛牡丹。
予獨愛蓮之出淤泥而不染,濯清漣而不妖,中通外直,不蔓不枝,香遠益清,亭亭淨植,可遠觀而不可褻玩焉。
予謂菊,花之隱逸者也;牡丹,花之富貴者也;蓮,花之君子者也。
噫!菊之愛,陶後鮮有聞。蓮之愛,同予者何人?牡丹之愛,宜乎眾矣!
注意:如果檔案比較大,一次性讀取整個檔案會佔用很大的記憶體,影響執行效率。
建議讀取小檔案時使用,不太適用於大檔案的讀取。
當讀取小檔案時,使用ioutil
效率明顯優於file.Read()
和bufio
,但如果是大檔案,bufio
讀取會更快,效率更高。
語法:
func OpenFile(name string, flag int, perm uint32) (file *File, err Error)
引數
os.OpenFile()
函數能夠以指定模式開啟檔案,從而實現檔案寫入相關功能。
模式flag種類:
模式 | 含義 |
---|---|
os.O_WRONLY | 只寫 |
os.O_CREATE | 如果不存在檔案,建立檔案 |
os.O_RDONLY | 唯讀 |
os.O_RDWR | 可讀可寫 |
os.O_TRUNC | 開啟時清空檔案原先內容 |
os.O_APPEND | 追加 |
若同時想用多種可用|
拼接不同模式。
檔案許可權perm:
使用4位元8進位制數
來表示三種型別使用者的許可權,首位取0,形式即0XXX
。
每位數位所代表的許可權:讀r=4,寫w=2,可執行x=1
數位 | r | w | x | 許可權 |
---|---|---|---|---|
0 | - | - | - | 所有許可權均無 |
1 | - | - | x | 可執行 |
2 | - | w | - | 可寫 |
3 | - | w | x | 可寫,可執行 |
4 | r | - | - | 可讀 |
5 | r | - | x | 可讀,可執行 |
6 | r | w | - | 可讀,可寫 |
7 | r | w | x | 可讀,可寫,可執行 |
常使用的0644
(-rw-r--r--
),表示檔案所有者可讀寫,同組使用者及其他使用者只可讀。
Write語法:
func (file *File) Write(b []byte) (n int, err Error)
引數
返回值:
使用 Write 方法寫檔案,接受的 引數 是一個要寫入的檔案內容的 位元組 陣列。如果寫入成功,返回成功寫入的位元組數,如果寫入失敗,返回 error 資訊。
WriteString語法:
func (f *File) WriteString(s string) (n int, err error)
引數
返回值:
使用 WriteString 方法寫檔案,接受的引數是一個要寫入的檔案內容的 字串。如果寫入成功,返回成功寫入的位元組數,如果寫入失敗,返回 error 資訊。
範例:
package main import ( "fmt" "os" ) //建立並寫入資料 //Write 和 WriteString func main() { //os.O_CREATE|os.O_RDWR:如果不存在檔案,建立檔案,可讀可寫 //0666對應:-rw-rw-rw- file, err := os.OpenFile("D:/bb.txt", os.O_CREATE|os.O_RDWR, 0666) if err != nil { fmt.Println("open file failed,err:",err) return } defer file.Close() str := "Hello Golangrn" file.Write([]byte(str)) //寫入位元組切片資料 file.WriteString("直接寫入的字串資料") //直接寫入字串資料 }
語法:
func NewWriter(w io.Writer) *Writer
func (b *Writer) WriteString(s string) (int, error)
func (b *Writer) Flush() error
將要寫入的內容寫入快取中,在執行flush的時候才會被寫到磁碟。
範例:
package main import ( "bufio" "fmt" "os" ) //bufio.NewWriter func main() { //1、開啟檔案 file,err := os.OpenFile("D:/cc.txt",os.O_CREATE|os.O_TRUNC|os.O_WRONLY,0666) if err != nil { fmt.Println("open file failed,err:",err) return } //5、關閉檔案流 defer file.Close() //2、建立writer物件 writer := bufio.NewWriter(file) for i := 0; i < 10; i++ { writer.WriteString("Hello Golangrn") //3、將資料先寫入快取 } writer.Flush() //4、將快取中的內容寫入檔案 }
語法:
func WriteFile(filename string, data []byte, perm os.FileMode) error
引數
返回值
使用 WriteFile 方法寫檔案,接受的第一個 引數 是一個 string 型別 的檔名,第二個引數是一個要寫入的檔案內容的 byte 陣列,最後一個引數是檔案的許可權。如果寫入成功,返回空的 error 資訊,如果寫入失敗,返回 error 資訊。
範例:
package main import ( "fmt" "io/ioutil" ) //ioutil.WriteFile func main() { str := "Hello Golang" err := ioutil.WriteFile("D:/dd.txt", []byte(str), 0666) if err != nil { fmt.Println("write file failed,err:",err) return } }
package main import ( "fmt" "io/ioutil" ) //複製檔案 //ioutil 進行復制 //編寫一個函數,接收兩個檔案路徑 srcFileName dstFileName func CopyFile(srcFileName string,dstFileName string)(err error){ input, err := ioutil.ReadFile(srcFileName) if err != nil { fmt.Println(err) return err } err = ioutil.WriteFile(dstFileName, input, 0644) if err != nil { fmt.Println("Error creating",dstFileName) fmt.Println(err) return err } return nil } func main() { srcFile := "D:/aa.zip" dstFile := "D:/bb.zip" err := CopyFile(srcFile, dstFile) if err == nil { fmt.Printf("拷貝完成n") }else { fmt.Printf("拷貝錯誤 err=%vn",err) } }
package main import ( "fmt" "io" "os" ) //複製資料 func CopyFile(srcFileName string,dstFileName string)(err error){ source, _ := os.Open(srcFileName) destination, _ := os.OpenFile(dstFileName, os.O_CREATE|os.O_WRONLY, 0666) buf := make([]byte, 128) for { n, err := source.Read(buf) if err != nil && err != io.EOF { return err } if n == 0 { break } if _,err := destination.Write(buf[:n]); err != nil { return err } } return nil } func main() { srcFile := "D:/aa.zip" dstFile := "D:/bb.zip" err := CopyFile(srcFile, dstFile) if err == nil { fmt.Printf("拷貝完成n") }else { fmt.Printf("拷貝錯誤 err=%vn",err) } }
package main import ( "fmt" "os" ) func main() { //檔案重新命名 err01 := os.Rename("D:/aa.txt","D:/ee.txt") //只能同盤操作 if err01 != nil { fmt.Println(err01) } //建立目錄 err02 := os.Mkdir("D:/aa", 0666) if err02 != nil { fmt.Println(err02) } //一次建立多個目錄 err03 := os.MkdirAll("D:/aa/bb/cc",0666) //建立多級目錄 if err03 != nil { fmt.Println(err03) } //刪除目錄和檔案 err04 := os.Remove("D:/ee.txt") if err04 != nil { fmt.Println(err04) } //一次刪除多個目錄或者檔案 err05 := os.RemoveAll("D:/aa") if err05 != nil { fmt.Println(err05) } }
到此這篇關於Golang檔案讀寫操作詳情的文章就介紹到這了,更多相關Go檔案操作內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45