Go語(yǔ)言文件操作

本文主要介紹了Go語(yǔ)言中文件讀寫的相關(guān)操作。

文件是什么?

計(jì)算機(jī)中的文件是存儲(chǔ)在外部介質(zhì)(通常是磁盤)上的數(shù)據(jù)集合,文件分為文本文件和二進(jìn)制文件铜异。

打開(kāi)和關(guān)閉文件
os.Open()函數(shù)能夠打開(kāi)一個(gè)文件,返回一個(gè)*File和一個(gè)err秸架。對(duì)得到的文件實(shí)例調(diào)用close()方法能夠關(guān)閉文件揍庄。

package main

import (
    "fmt"
    "os"
)

func main() {
    // 只讀方式打開(kāi)當(dāng)前目錄下的main.go文件
    file, err := os.Open("./main.go")
    if err != nil {
        fmt.Println("open file failed!, err:", err)
        return
    }
    // 關(guān)閉文件
    file.Close()
}

為了防止文件忘記關(guān)閉,我們通常使用defer注冊(cè)文件關(guān)閉語(yǔ)句东抹。

讀取文件

file.Read()

基本使用
Read方法定義如下:

func (f *File) Read(b []byte) (n int, err error)

它接收一個(gè)字節(jié)切片蚂子,返回讀取的字節(jié)數(shù)和可能的具體錯(cuò)誤沃测,讀到文件末尾時(shí)會(huì)返回0和io.EOF。 舉個(gè)例子:


func main() {
    // 只讀方式打開(kāi)當(dāng)前目錄下的main.go文件
    file, err := os.Open("./main.go")
    if err != nil {
        fmt.Println("open file failed!, err:", err)
        return
    }
    defer file.Close()
    // 使用Read方法讀取數(shù)據(jù)
    var tmp = make([]byte, 128)
    n, err := file.Read(tmp)
    if err == io.EOF {
        fmt.Println("文件讀完了")
        return
    }
    if err != nil {
        fmt.Println("read file failed, err:", err)
        return
    }
    fmt.Printf("讀取了%d字節(jié)數(shù)據(jù)\n", n)
    fmt.Println(string(tmp[:n]))
}

循環(huán)讀取
使用for循環(huán)讀取文件中的所有數(shù)據(jù)食茎。

func main() {
    // 只讀方式打開(kāi)當(dāng)前目錄下的main.go文件
    file, err := os.Open("./main.go")
    if err != nil {
        fmt.Println("open file failed!, err:", err)
        return
    }
    defer file.Close()
    // 循環(huán)讀取文件
    var content []byte
    var tmp = make([]byte, 128)
    for {
        n, err := file.Read(tmp)
        if err == io.EOF {
            fmt.Println("文件讀完了")
            break
        }
        if err != nil {
            fmt.Println("read file failed, err:", err)
            return
        }
        content = append(content, tmp[:n]...)
    }
    fmt.Println(string(content))
}

bufio讀取文件
bufio是在file的基礎(chǔ)上封裝了一層API蒂破,支持更多的功能。

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
)

// bufio按行讀取示例
func main() {
    file, err := os.Open("./xx.txt")
    if err != nil {
        fmt.Println("open file failed, err:", err)
        return
    }
    defer file.Close()
    reader := bufio.NewReader(file)
    for {
        line, err := reader.ReadString('\n') //注意是字符
        if err == io.EOF {
            if len(line) != 0 {
                fmt.Println(line)
            }
            fmt.Println("文件讀完了")
            break
        }
        if err != nil {
            fmt.Println("read file failed, err:", err)
            return
        }
        fmt.Print(line)
    }
}

ioutil讀取整個(gè)文件
io/ioutil包的ReadFile方法能夠讀取完整的文件别渔,只需要將文件名作為參數(shù)傳入附迷。

package main

import (
    "fmt"
    "io/ioutil"
)

// ioutil.ReadFile讀取整個(gè)文件
func main() {
    content, err := ioutil.ReadFile("./main.go")
    if err != nil {
        fmt.Println("read file failed, err:", err)
        return
    }
    fmt.Println(string(content))
}

文件寫入操作
os.OpenFile()函數(shù)能夠以指定模式打開(kāi)文件,從而實(shí)現(xiàn)文件寫入相關(guān)功能钠糊。

func OpenFile(name string, flag int, perm FileMode) (*File, error) {
    ...
}

其中:

name:要打開(kāi)的文件名 flag:打開(kāi)文件的模式挟秤。 模式有以下幾種:

模式 含義
os.O_WRONLY 只寫
os.O_CREATE 創(chuàng)建文件
os.O_RDONLY 只讀
os.O_RDWR 讀寫
os.O_TRUNC 清空
os.O_APPEND 追加

perm:文件權(quán)限壹哺,一個(gè)八進(jìn)制數(shù)抄伍。r(讀)04,w(寫)02管宵,x(執(zhí)行)01截珍。

Write和WriteString

func main() {
    file, err := os.OpenFile("xx.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
    if err != nil {
        fmt.Println("open file failed, err:", err)
        return
    }
    defer file.Close()
    str := "hello 沙河"
    file.Write([]byte(str))       //寫入字節(jié)切片數(shù)據(jù)
    file.WriteString("hello 小王子") //直接寫入字符串?dāng)?shù)據(jù)
}

bufio.NewWriter

func main() {
    file, err := os.OpenFile("xx.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
    if err != nil {
        fmt.Println("open file failed, err:", err)
        return
    }
    defer file.Close()
    writer := bufio.NewWriter(file)
    for i := 0; i < 10; i++ {
        writer.WriteString("hello沙河\n") //將數(shù)據(jù)先寫入緩存
    }
    writer.Flush() //將緩存中的內(nèi)容寫入文件
}

ioutil.WriteFile

func main() {
    str := "hello 沙河"
    err := ioutil.WriteFile("./xx.txt", []byte(str), 0666)
    if err != nil {
        fmt.Println("write file failed, err:", err)
        return
    }
}

練習(xí)
copyFile
借助io.Copy()實(shí)現(xiàn)一個(gè)拷貝文件函數(shù)。

// CopyFile 拷貝文件函數(shù)
func CopyFile(dstName, srcName string) (written int64, err error) {
    // 以讀方式打開(kāi)源文件
    src, err := os.Open(srcName)
    if err != nil {
        fmt.Printf("open %s failed, err:%v.\n", srcName, err)
        return
    }
    defer src.Close()
    // 以寫|創(chuàng)建的方式打開(kāi)目標(biāo)文件
    dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
    if err != nil {
        fmt.Printf("open %s failed, err:%v.\n", dstName, err)
        return
    }
    defer dst.Close()
    return io.Copy(dst, src) //調(diào)用io.Copy()拷貝內(nèi)容
}
func main() {
    _, err := CopyFile("dst.txt", "src.txt")
    if err != nil {
        fmt.Println("copy file failed, err:", err)
        return
    }
    fmt.Println("copy done!")
}

實(shí)現(xiàn)一個(gè)cat命令
使用文件操作相關(guān)知識(shí)箩朴,模擬實(shí)現(xiàn)linux平臺(tái)cat命令的功能岗喉。

package main

import (
    "bufio"
    "flag"
    "fmt"
    "io"
    "os"
)

// cat命令實(shí)現(xiàn)
func cat(r *bufio.Reader) {
    for {
        buf, err := r.ReadBytes('\n') //注意是字符
        if err == io.EOF {
            break
        }
        fmt.Fprintf(os.Stdout, "%s", buf)
    }
}

func main() {
    flag.Parse() // 解析命令行參數(shù)
    if flag.NArg() == 0 {
        // 如果沒(méi)有參數(shù)默認(rèn)從標(biāo)準(zhǔn)輸入讀取內(nèi)容
        cat(bufio.NewReader(os.Stdin))
    }
    // 依次讀取每個(gè)指定文件的內(nèi)容并打印到終端
    for i := 0; i < flag.NArg(); i++ {
        f, err := os.Open(flag.Arg(i))
        if err != nil {
            fmt.Fprintf(os.Stdout, "reading from %s failed, err:%v\n", flag.Arg(i), err)
            continue
        }
        cat(bufio.NewReader(f))
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市炸庞,隨后出現(xiàn)的幾起案子钱床,更是在濱河造成了極大的恐慌,老刑警劉巖埠居,帶你破解...
    沈念sama閱讀 218,607評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件查牌,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡滥壕,警方通過(guò)查閱死者的電腦和手機(jī)纸颜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)绎橘,“玉大人胁孙,你說(shuō)我怎么就攤上這事〕屏郏” “怎么了涮较?”我有些...
    開(kāi)封第一講書人閱讀 164,960評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)冈止。 經(jīng)常有香客問(wèn)我法希,道長(zhǎng),這世上最難降的妖魔是什么靶瘸? 我笑而不...
    開(kāi)封第一講書人閱讀 58,750評(píng)論 1 294
  • 正文 為了忘掉前任苫亦,我火速辦了婚禮毛肋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘屋剑。我一直安慰自己润匙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布唉匾。 她就那樣靜靜地躺著孕讳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪巍膘。 梳的紋絲不亂的頭發(fā)上厂财,一...
    開(kāi)封第一講書人閱讀 51,604評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音峡懈,去河邊找鬼璃饱。 笑死,一個(gè)胖子當(dāng)著我的面吹牛肪康,可吹牛的內(nèi)容都是我干的荚恶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,347評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼磷支,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼谒撼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起雾狈,我...
    開(kāi)封第一講書人閱讀 39,253評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤廓潜,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后善榛,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體辩蛋,經(jīng)...
    沈念sama閱讀 45,702評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評(píng)論 3 336
  • 正文 我和宋清朗相戀三年锭弊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了堪澎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,015評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡味滞,死狀恐怖樱蛤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情剑鞍,我是刑警寧澤昨凡,帶...
    沈念sama閱讀 35,734評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站蚁署,受9級(jí)特大地震影響便脊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜光戈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評(píng)論 3 330
  • 文/蒙蒙 一哪痰、第九天 我趴在偏房一處隱蔽的房頂上張望遂赠。 院中可真熱鬧,春花似錦晌杰、人聲如沸跷睦。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,934評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)抑诸。三九已至,卻和暖如春爹殊,著一層夾襖步出監(jiān)牢的瞬間蜕乡,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,052評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工梗夸, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留层玲,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,216評(píng)論 3 371
  • 正文 我出身青樓绒瘦,卻偏偏與公主長(zhǎng)得像称簿,于是被迫代替她去往敵國(guó)和親扣癣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子惰帽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 文件的打開(kāi)和關(guān)閉 os包中提供了方法叫做Open,就是專門用于打開(kāi)某一個(gè)文件的 注意點(diǎn):如果文件不存在不會(huì)自動(dòng)創(chuàng)建...
    AuglyXu閱讀 1,437評(píng)論 0 6
  • Go語(yǔ)言操作文件 文件的打開(kāi)與關(guān)閉 文件的打開(kāi)在Go語(yǔ)言的os包中提供了一個(gè)函數(shù), 叫做Open, 就是專門用于打...
    喝酸奶要舔蓋__閱讀 223評(píng)論 0 0
  • 如何打開(kāi)和關(guān)閉文件 在Go語(yǔ)言中的OS包提供了一個(gè)函數(shù),叫做open,就是專門用來(lái)打開(kāi)文件的 在Go語(yǔ)言中OS包中...
    超級(jí)皮波9閱讀 591評(píng)論 0 0
  • 文件讀取 讀寫參數(shù) 文件打開(kāi)模式 權(quán)限控制 讀取例子 os.Open || os.OpenFile readlin...
    程序員小飯閱讀 413評(píng)論 0 1
  • 文章目錄 文件信息接口os.FileInfo 文件的常規(guī)操作 (os包) 文件的讀取和寫入 (io及os包) io...
    __robin閱讀 5,891評(píng)論 0 4