首頁 > 軟體

GO檔案建立及讀寫操作範例詳解

2022-04-14 22:00:27

三種檔案操作比較

ioutil
bufio
os.File

當檔案較小(KB 級別)時,ioutil > bufio > os。
當檔案大小比較常規(MB 級別)時,三者差別不大,但 bufio 又是已經顯現出來。
當檔案較大(GB 級別)時,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("aaaanbbbnccccn啦啦啦啦"),0777)
}

ioutil.ReadAll 讀

// 比較浪費記憶體,解決方法,百度查詢
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())  //檢視讀寫許可權-rw-r--r--
		fmt.Println(file.ModTime())  //檔案建立時間
	}
}

ioutil.TempDir 建立臨時目錄

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

ioutil.TempFile 建立臨時檔案

// 建立臨時檔案,以jeff開頭,eg:jeff067576
func Ioutil_file()  {
	//以讀寫模式開啟該檔案並返回os.File指標
	path,_:=ioutil.TempFile("./","jeff")
	fmt.Println(path) //返回os.File指標
}

os.file

方法

os.Create() //建立檔案,如果有該檔案則會清空檔案
os.Open()  // 唯讀方式開啟檔案
os.OpenFile(檔名,開啟方式,開啟許可權)
Write() //寫入
Read()  //讀取

os.OpenFile()

OpenFile( )這個函數有三個引數

第一個參數列示開啟檔案的路徑

第二個參數列示模式,常見的模式有

O_RDONLY(唯讀模式),

O_WRONLY(只寫模式),

O_RDWR(可讀可寫模式),

O_APPEND(追加模式)。

第三個引數,表示許可權,取值範圍(0-7)

表示如下:

0:沒有任何許可權
1:執行許可權(如果是可執行檔案,是可以執行的)
2:寫許可權
3:寫許可權與執行許可權
4:讀許可權
5:讀許可權與執行許可權
6:讀許可權與寫許可權
7:讀許可權,寫許可權,執行許可權

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()

建立檔案

將資料儲存到檔案之前,先要建立檔案。GO語言中提供了一個Create( )函數專門建立檔案.

該函數在建立檔案時,首先會判斷要建立的檔案是否存在,如果不存在,則建立,如果存在,會先將檔案中已有的資料清空。

同時,當檔案建立成功後,該檔案會預設的開啟,所以不用在執行開啟操作,可以直接向該檔案中寫入資料。

建立檔案的步驟:

(1)匯入“os”包,建立檔案,讀寫檔案的函數都在該包

(2)指定建立的檔案存放路徑以及檔名。

(3)執行Create( )函數,進行檔案建立

(4)關閉檔案

具體程式碼:

package main
import (
    "fmt"
    "os"
)
func main() {
    //os.Create(檔名) 檔名  可以寫絕對路徑和相對路徑
    //返回值  檔案指標 錯誤資訊
    fp,err := os.Create("./a.txt")
    if err!=nil{
        //檔案建立失敗
        /*
        1.路徑不存在
        2.檔案許可權
        3.程式開啟檔案上限
         */
        fmt.Println("檔案建立失敗")
        return
    }
    //讀寫檔案
    defer fp.Close()
    //關閉檔案
    //如果開啟檔案不關閉 造成記憶體的浪費  程式開啟檔案的上限
    //fp.Close()
}

寫入資料三種方式

第一種-WriteString( )函數

WriteString( )方法預設返回兩個引數,第一個引數,指的是寫入檔案的資料長度,第二個引數記錄的是錯誤資訊
WriteString( )方法預設寫到檔案中的資料是不換行的。如果想換行,可以採用如下的方式:
//n不會換行  原因 在windows文字檔案中換行rn  回車  在linux中換行n
fp.WriteString("hello worldrn")
fp.WriteString("性感荷官線上發牌")

檔案開啟以後,可以向檔案中寫資料,可以使用WriteString( )方法。

//反斜槓 跳脫字元
//在寫路徑時可以使用/正斜槓代替反斜槓
fp,err := os.Create("D:/a.txt")
if err!=nil{
    //檔案建立失敗
    /*
    1.路徑不存在
    2.檔案許可權
    3.程式開啟檔案上限
     */
    fmt.Println("檔案建立失敗")
    return
}
//寫檔案
//n不會換行  原因 在windows文字檔案中換行rn  回車  在linux中換行n
fp.WriteString("hello worldrn")
fp.WriteString("性感荷官線上發牌")
defer fp.Close()
//關閉檔案
//如果開啟檔案不關閉 造成記憶體的浪費  程式開啟檔案的上限
//fp.Close()

第二種-Write( )函數

在這裡要注意的是,使用Write( )函數寫資料時,引數為位元組切片,所以需要將字串轉換成位元組切片。該方法返回的也是寫入檔案資料的長度

fp,err := os.Create("D:/a.txt")
if err!=nil{
    //檔案建立失敗
    /*
    1.路徑不存在
    2.檔案許可權
    3.程式開啟檔案上限
     */
    fmt.Println("檔案建立失敗")
    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( )函數

在指定的位置寫入資料,以下程式中Seek( )函數返回值儲存到變數n中,值為檔案末尾的位置。WriteAt( )也返回的是寫入的資料長度。

fp,err := os.Create("D:/a.txt")
if err!=nil{
    //檔案建立失敗
    /*
    1.路徑不存在
    2.檔案許可權
    3.程式開啟檔案上限
     */
    fmt.Println("檔案建立失敗")
    return
}
//寫操作
//獲取遊標流位置'
//獲取檔案起始到結尾有多少個字元
//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 讀取檔案

如果檔案已經存在,並且也已經有資料了,那麼可以直接讀取該檔案中的內容。

讀取檔案的基本流程如下:

(1)開啟要讀取的檔案

(2)對檔案進行讀取

(3)關閉檔案

在向檔案中寫資料的時候,使用的是Write,那麼讀取檔案中的資料,使用的是Read.

關於Read( )函數的使用如下:

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, err1 := fp.Read(buf)
    if err1 != nil && err1 != io.EOF {
        fmt.Println("err1=", err1)
        return
    }
    fmt.Println("buf=", string(buf[:n]))

    //關閉檔案
    defer fp.Close()

}

Open( )是開啟檔案,與OpenFile( )的區別是,Open( )只有讀的許可權

在使用Read( )函數讀取檔案中的內容時,需要一個切片型別,而定義切片時型別為字元陣列,將檔案中的內容儲存在切片中,同時除了對其判斷是否出錯時以外,還要判斷是否到檔案末尾(這裡需要匯入io包)。

Read( )函數返回的是從檔案中讀取的資料的長度。最後,輸出切片中儲存的檔案資料,注意,讀取的是從最開始到整個資料長度,因為有可能儲存到切片中的資料達不到切片的總長度(也是切片時2k,但是從檔案中讀取的資料有可能只有1k)

按行讀取

上面我們是將檔案的內容全部讀取出來,然後存放在切片中,我們也可以每次唯讀取一行資料。

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

1:開啟檔案

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

2:建立緩衝區

在使用ReadBytes( )函數讀取資料時,需要用到緩衝區,所謂緩衝區就是儲存資料的區域,也就是先將從檔案中讀取的資料儲存在該區域內,然後在將區域中的資料取出來,寫到磁碟上。提供緩衝區的原因是:

為了緩和 CPU 與磁碟裝置之間速度不匹配矛盾。檔案緩衝區是用以暫時存放讀寫期間的檔案資料而在記憶體區預留的一定空間。

//建立檔案緩衝區
r := bufio.NewReader(fp)

3:迴圈讀取檔案中的內容,直到檔案末尾位置。

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

在使用ReadBytes( )函數時,傳遞的引數是‘n’,表示遇到’n’就結束,所以使用了死迴圈(每回圈一次,讀取一行資料),只有到檔案末尾了,才退出整個迴圈。最後,將讀取的資料列印出來,注意ReadBytes( )返回的是位元組切片,所以在列印時要轉換成字串。

4:最後關閉檔案

//關閉檔案
defer fp.Close()

現在我們已經完成了檔案的建立,讀取,以及將資料儲存到檔案的操作,在對檔案操作時,我們需要指定檔案的路徑。

關於路徑,有兩種情況:

第一:相對路徑,所謂相對路徑指的是檔案相對於應用程式的路徑。例如:上面我們一隻使用的a.txt,這個檔案,該檔案存放的位置與可執行檔案儲存的路徑是一樣的。

第二:絕對路徑:指的是通過給定的這個路徑直接能在我的電腦中找到這個檔案。例如:D:Info.txt,

  • 建議我們以後在開發中使用相對路徑

檔案操作案例

檔案拷貝,將已有的檔案複製一份,同時重新命名。

基本的思路:

(1)讓使用者輸入要拷貝的檔案的名稱(原始檔)以及目的檔案的名稱

(2)建立目的檔案

(3)開啟原始檔,並且讀取該檔案中的內容

(4)將從原始檔中讀取的內容寫到目的檔案中。

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
}
//操作完畢,需要關閉檔案
defer sF.Close()
defer dF.Close()
//核心處理,從原始檔讀取內容,往目的檔案寫,讀多少寫多少
buf := make([]byte,4*1024)//4k大小臨時緩衝區
for{
    n,err := sF.Read(buf)//從原始檔讀取內容,每次讀取一部分
    if err != nil{
        fmt.Println("err=",err)
        if err == io.EOF{//檔案讀取完畢
            break
        }
    }
    //往目的檔案寫,讀多少寫多少
    dF.Write(buf[:n])
}

以上就是GO檔案建立及讀寫操作範例詳解的詳細內容,更多關於GO檔案建立讀寫操作的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com