溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

GO文件創(chuàng)建及讀寫操作的方法

發(fā)布時(shí)間:2022-04-15 10:29:13 來源:億速云 閱讀:147 作者:iii 欄目:開發(fā)技術(shù)

本文小編為大家詳細(xì)介紹“GO文件創(chuàng)建及讀寫操作的方法”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“GO文件創(chuàng)建及讀寫操作的方法”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識吧。

    三種文件操作比較

    ioutil
    bufio
    os.File
    
    當(dāng)文件較小(KB 級別)時(shí),ioutil > bufio > os。
    當(dāng)文件大小比較常規(guī)(MB 級別)時(shí),三者差別不大,但 bufio 又是已經(jīng)顯現(xiàn)出來。
    當(dāng)文件較大(GB 級別)時(shí),bufio > os > ioutil。

    ioutil

    ioutil.ReadFile讀

    //讀
    func Ioutil_read() {
    	file, _ := ioutil.ReadFile("./write.txt")
    	fmt.Println(string(file))
    }

    ioutil.WriteFile 寫

    //寫
    func Ioutil_write()  {
    	ioutil.WriteFile("./write.txt",[]byte("aaaa\nbbb\ncccc\n啦啦啦啦"),0777)
    }

    ioutil.ReadAll 讀

    // 比較浪費(fèi)內(nèi)存,解決方法,百度查詢
    file,_ := os.Open("./write.txt")
    b,_:=ioutil.ReadAll(file)
    fmt.Println(string(b))

    ioutil.ReadDir 查看路徑下目錄信息

    func Ioutil_ReadDir()  {
    	dir,_:=ioutil.ReadDir("./")
    	for _,file := range dir{
    		fmt.Println(file.Name())  //文件名字
    		fmt.Println(file.Size())  //文件大小
    		fmt.Println(file.IsDir())  //判斷是否為目錄
    		fmt.Println(file.Mode())  //查看讀寫權(quán)限-rw-r--r--
    		fmt.Println(file.ModTime())  //文件創(chuàng)建時(shí)間
    	}
    }

    ioutil.TempDir 創(chuàng)建臨時(shí)目錄

    // 創(chuàng)建臨時(shí)目錄,以jeff開頭,eg:jeff0123755
    func Ioutil_Tempdir()  {
    	path,_ := ioutil.TempDir("./","jeff")
    	fmt.Println(path)  //返回臨時(shí)目錄路徑
    }

    ioutil.TempFile 創(chuàng)建臨時(shí)文件

    // 創(chuàng)建臨時(shí)文件,以jeff開頭,eg:jeff067576
    func Ioutil_file()  {
    	//以讀寫模式打開該文件并返回os.File指針
    	path,_:=ioutil.TempFile("./","jeff")
    	fmt.Println(path) //返回os.File指針
    }

    os.file

    方法

    os.Create() //創(chuàng)建文件,如果有該文件則會清空文件
    os.Open()  // 只讀方式打開文件
    os.OpenFile(文件名,打開方式,打開權(quán)限)
    Write() //寫入
    Read()  //讀取

    os.OpenFile()

    OpenFile( )這個(gè)函數(shù)有三個(gè)參數(shù),第一個(gè)參數(shù)表示打開文件的路徑,第二個(gè)參數(shù)表示模式,常見的模式有
    
    O_RDONLY(只讀模式),O_WRONLY(只寫模式),O_RDWR(可讀可寫模式),O_APPEND(追加模式)。
    
    第三個(gè)參數(shù),表示權(quán)限,取值范圍(0-7)
    表示如下:
    
    0:沒有任何權(quán)限
    1:執(zhí)行權(quán)限(如果是可執(zhí)行文件,是可以運(yùn)行的)
    2:寫權(quán)限
    3:寫權(quán)限與執(zhí)行權(quán)限
    4:讀權(quán)限
    5:讀權(quán)限與執(zhí)行權(quán)限
    6:讀權(quán)限與寫權(quán)限
    7:讀權(quán)限,寫權(quán)限,執(zhí)行權(quán)限
    fp,err := os.OpenFile("D:/a.txt",os.O_RDWR,6)
    if err!=nil {
        fmt.Println("打開文件失敗")
    }
    
    fp.WriteString("hello")
    fp.WriteAt([]byte("hello"),25)
    defer fp.Close()

    創(chuàng)建文件

    將數(shù)據(jù)存儲到文件之前,先要創(chuàng)建文件。GO語言中提供了一個(gè)Create( )函數(shù)專門創(chuàng)建文件.

    該函數(shù)在創(chuàng)建文件時(shí),首先會判斷要創(chuàng)建的文件是否存在,如果不存在,則創(chuàng)建,如果存在,會先將文件中已有的數(shù)據(jù)清空。

    同時(shí),當(dāng)文件創(chuàng)建成功后,該文件會默認(rèn)的打開,所以不用在執(zhí)行打開操作,可以直接向該文件中寫入數(shù)據(jù)。

    創(chuàng)建文件的步驟:

    (1)導(dǎo)入“os”包,創(chuàng)建文件,讀寫文件的函數(shù)都在該包

    (2)指定創(chuàng)建的文件存放路徑以及文件名。

    (3)執(zhí)行Create( )函數(shù),進(jìn)行文件創(chuàng)建

    (4)關(guān)閉文件

    具體代碼:

    package main
    
    import (
        "fmt"
        "os"
    )
    
    func main() {
        //os.Create(文件名) 文件名  可以寫絕對路徑和相對路徑
        //返回值  文件指針 錯誤信息
        fp,err := os.Create("./a.txt")
        if err!=nil{
            //文件創(chuàng)建失敗
            /*
            1.路徑不存在
            2.文件權(quán)限
            3.程序打開文件上限
             */
            fmt.Println("文件創(chuàng)建失敗")
            return
        }
    
        //讀寫文件
    
        defer fp.Close()
    
        //關(guān)閉文件
        //如果打開文件不關(guān)閉 造成內(nèi)存的浪費(fèi)  程序打開文件的上限
        //fp.Close()
    }

    寫入數(shù)據(jù)三種方式

    第一種-WriteString( )函數(shù)

    WriteString( )方法默認(rèn)返回兩個(gè)參數(shù),第一個(gè)參數(shù),指的是寫入文件的數(shù)據(jù)長度,第二個(gè)參數(shù)記錄的是錯誤信息
    WriteString( )方法默認(rèn)寫到文件中的數(shù)據(jù)是不換行的。如果想換行,可以采用如下的方式:
    
    //\n不會換行  原因 在windows文本文件中換行\(zhòng)r\n  回車  在linux中換行\(zhòng)n
    fp.WriteString("hello world\r\n")
    fp.WriteString("性感荷官在線發(fā)牌")

    文件打開以后,可以向文件中寫數(shù)據(jù),可以使用WriteString( )方法。

    //\反斜杠 轉(zhuǎn)義字符
    //在寫路徑時(shí)可以使用/正斜杠代替\反斜杠
    fp,err := os.Create("D:/a.txt")
    if err!=nil{
        //文件創(chuàng)建失敗
        /*
        1.路徑不存在
        2.文件權(quán)限
        3.程序打開文件上限
         */
        fmt.Println("文件創(chuàng)建失敗")
        return
    }
    
    //寫文件
    
    //\n不會換行  原因 在windows文本文件中換行\(zhòng)r\n  回車  在linux中換行\(zhòng)n
    fp.WriteString("hello world\r\n")
    fp.WriteString("性感荷官在線發(fā)牌")
    
    
    defer fp.Close()
    
    //關(guān)閉文件
    //如果打開文件不關(guān)閉 造成內(nèi)存的浪費(fèi)  程序打開文件的上限
    //fp.Close()

    第二種-Write( )函數(shù)

    在這里要注意的是,使用Write( )函數(shù)寫數(shù)據(jù)時(shí),參數(shù)為字節(jié)切片,所以需要將字符串轉(zhuǎn)換成字節(jié)切片。該方法返回的也是寫入文件數(shù)據(jù)的長度
    fp,err := os.Create("D:/a.txt")
    if err!=nil{
        //文件創(chuàng)建失敗
        /*
        1.路徑不存在
        2.文件權(quán)限
        3.程序打開文件上限
         */
        fmt.Println("文件創(chuàng)建失敗")
        return
    }
    
    //寫操作
    //slice := []byte{'h','e','l','l','o'}
    //count,err1 := fp.Write(slice)
    count,err1 := fp.Write([]byte("性感老王在線授課"))
    
    if err1!=nil {
        fmt.Println("寫入文件失敗")
        return
    }else {
        fmt.Println(count)
    }
    
    defer fp.Close()

    第三種-WriteAt( )函數(shù)

    在指定的位置寫入數(shù)據(jù),以下程序中Seek( )函數(shù)返回值存儲到變量n中,值為文件末尾的位置。WriteAt( )也返回的是寫入的數(shù)據(jù)長度。

    fp,err := os.Create("D:/a.txt")
    if err!=nil{
        //文件創(chuàng)建失敗
        /*
        1.路徑不存在
        2.文件權(quán)限
        3.程序打開文件上限
         */
        fmt.Println("文件創(chuàng)建失敗")
        return
    }
    
    //寫操作
    //獲取光標(biāo)流位置'
    //獲取文件起始到結(jié)尾有多少個(gè)字符
    //count,_:=fp.Seek(0,os.SEEK_END)
    count,_:=fp.Seek(0,io.SeekEnd)
    fmt.Println(count)
    //指定位置寫入
    fp.WriteAt([]byte("hello world"),count)
    fp.WriteAt([]byte("hahaha"),0)
    fp.WriteAt([]byte("秀兒"),19)
    
    defer fp.Close()

    讀取文件

    Read 讀取文件

    如果文件已經(jīng)存在,并且也已經(jīng)有數(shù)據(jù)了,那么可以直接讀取該文件中的內(nèi)容。

    讀取文件的基本流程如下:

    (1)打開要讀取的文件

    (2)對文件進(jìn)行讀取

    (3)關(guān)閉文件

    在向文件中寫數(shù)據(jù)的時(shí)候,使用的是Write,那么讀取文件中的數(shù)據(jù),使用的是Read.

    關(guān)于Read( )函數(shù)的使用如下:

    package main
    
    import (
        "fmt"
        "io"
        "os"
    )
    func main() {
    
        //打開文件
        fp, err := os.Open("D:/a.txt")
        if err != nil {
            fmt.Println("err=", err)
            return
        }
    
        buf := make([]byte, 1024*2) //2k大小
        //n代表從文件讀取內(nèi)容的長度
        n, err1 := fp.Read(buf)
        if err1 != nil && err1 != io.EOF {
            fmt.Println("err1=", err1)
            return
        }
        fmt.Println("buf=", string(buf[:n]))
    
        //關(guān)閉文件
        defer fp.Close()
    
    }

    Open( )是打開文件,與OpenFile( )的區(qū)別是,Open( )只有讀的權(quán)限

    在使用Read( )函數(shù)讀取文件中的內(nèi)容時(shí),需要一個(gè)切片類型,而定義切片時(shí)類型為字符數(shù)組,將文件中的內(nèi)容保存在切片中,同時(shí)除了對其判斷是否出錯時(shí)以外,還要判斷是否到文件末尾(這里需要導(dǎo)入io包)。

    Read( )函數(shù)返回的是從文件中讀取的數(shù)據(jù)的長度。最后,輸出切片中存儲的文件數(shù)據(jù),注意,讀取的是從最開始到整個(gè)數(shù)據(jù)長度,因?yàn)橛锌赡艽鎯Φ角衅械臄?shù)據(jù)達(dá)不到切片的總長度(也是切片時(shí)2k,但是從文件中讀取的數(shù)據(jù)有可能只有1k)

    按行讀取

    上面我們是將文件的內(nèi)容全部讀取出來,然后存放在切片中,我們也可以每次只讀取一行數(shù)據(jù)。

    這需要用到bufio包中的ReadBytes函數(shù)。具體如下:

    1:打開文件

    fp, err := os.Open("D:/a.txt")
    if err != nil {
        fmt.Println("打開文件失敗", err)
        return
    }

    2:創(chuàng)建緩沖區(qū)

    在使用ReadBytes( )函數(shù)讀取數(shù)據(jù)時(shí),需要用到緩沖區(qū),所謂緩沖區(qū)就是存儲數(shù)據(jù)的區(qū)域,也就是先將從文件中讀取的數(shù)據(jù)存儲在該區(qū)域內(nèi),然后在將區(qū)域中的數(shù)據(jù)取出來,寫到磁盤上。提供緩沖區(qū)的原因是:

    為了緩和 CPU 與磁盤設(shè)備之間速度不匹配矛盾。文件緩沖區(qū)是用以暫時(shí)存放讀寫期間的文件數(shù)據(jù)而在內(nèi)存區(qū)預(yù)留的一定空間。

    //創(chuàng)建文件緩沖區(qū)
    r := bufio.NewReader(fp)

    3:循環(huán)讀取文件中的內(nèi)容,直到文件末尾位置。

    for {
        //遇到'\n'結(jié)束讀取,但是'\n'也讀取進(jìn)入
        buf,err := r.ReadBytes('\n')
        fmt.Println("buf = ",string(buf))
        if err != nil {
            if err == io.EOF {
                break
            }
            fmt.Println("err=",err)
        }
    }

    在使用ReadBytes( )函數(shù)時(shí),傳遞的參數(shù)是‘\n’,表示遇到’\n’就結(jié)束,所以使用了死循環(huán)(每循環(huán)一次,讀取一行數(shù)據(jù)),只有到文件末尾了,才退出整個(gè)循環(huán)。最后,將讀取的數(shù)據(jù)打印出來,注意ReadBytes( )返回的是字節(jié)切片,所以在打印時(shí)要轉(zhuǎn)換成字符串。

    4:最后關(guān)閉文件

    //關(guān)閉文件
    defer fp.Close()

    現(xiàn)在我們已經(jīng)完成了文件的創(chuàng)建,讀取,以及將數(shù)據(jù)保存到文件的操作,在對文件操作時(shí),我們需要指定文件的路徑。

    關(guān)于路徑,有兩種情況:

    第一:相對路徑,所謂相對路徑指的是文件相對于應(yīng)用程序的路徑。例如:上面我們一只使用的a.txt,這個(gè)文件,該文件存放的位置與可執(zhí)行文件存儲的路徑是一樣的。

    第二:絕對路徑:指的是通過給定的這個(gè)路徑直接能在我的電腦中找到這個(gè)文件。例如:D:\Info.txt,

    • 建議我們以后在開發(fā)中使用相對路徑

    文件操作案例

    文件拷貝,將已有的文件復(fù)制一份,同時(shí)重新命名。

    基本的思路:

    (1)讓用戶輸入要拷貝的文件的名稱(源文件)以及目的文件的名稱

    (2)創(chuàng)建目的文件

    (3)打開源文件,并且讀取該文件中的內(nèi)容

    (4)將從源文件中讀取的內(nèi)容寫到目的文件中。

    var srcFileName string
    var dstFileName string
    fmt.Printf("請輸入源文件名稱:")
    fmt.Scan(&srcFileName)
    fmt.Println("請輸入目的文件名稱:")
    fmt.Scan(&dstFileName)
    if srcFileName == dstFileName {
        fmt.Println("源文件和目的文件名字不能相同")
        return
    }
    //只讀方式打開源文件
    sF,err1 := os.Open(srcFileName)
    if err1 != nil {
        fmt.Println("err1=",err1)
        return
    }
    //新建目的文件
    dF,err2 := os.Create(dstFileName)
    if err2 != nil{
        fmt.Println("err2=",err2)
        return
    }
    //操作完畢,需要關(guān)閉文件
    defer sF.Close()
    defer dF.Close()
    //核心處理,從源文件讀取內(nèi)容,往目的文件寫,讀多少寫多少
    buf := make([]byte,4*1024)//4k大小臨時(shí)緩沖區(qū)
    for{
        n,err := sF.Read(buf)//從源文件讀取內(nèi)容,每次讀取一部分
        if err != nil{
            fmt.Println("err=",err)
            if err == io.EOF{//文件讀取完畢
                break
            }
        }
        //往目的文件寫,讀多少寫多少
        dF.Write(buf[:n])
    }

    讀到這里,這篇“GO文件創(chuàng)建及讀寫操作的方法”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點(diǎn)還需要大家自己動手實(shí)踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    go
    AI