Golang檔案操作整理

2022-06-13 05:54:10 字數 4441 閱讀 4921

檔案建立

檔案刪除

檔案刪除的時候,不管是普通檔案還是目錄檔案,都可以用err:=os.remove(filename)這樣的操作來執行。當然要是想移除整個資料夾,直接使用removeall(path string)操作即可。可以看一下removeall函式的內部實現,整體上就是遍歷,遞迴的操作過程,其他的類似的檔案操作都可以用類似的模板來實現,下面以removeall函式為模板,進行一下具體的分析,注意考慮到各種情況:

func removeall(path string) error 

// otherwise, is this a directory we need to recurse into?

// 目錄裡面還有檔案 需要遞迴處理

// 注意lstat和stat函式的區別,兩個都是返回檔案的狀態資訊

//lstat多了處理link檔案的功能,會返回linked檔案的資訊,而state直接返回的是link檔案所指向的檔案的資訊

dir, serr := lstat(path)

if serr != nil

return serr

}//不是目錄

if !dir.isdir()

// directory.

fd, err := open(path)

if err != nil

return err

}// remove contents & return first error.

err = nil

//遞迴遍歷目錄中的檔案 如果引數n<=0則將全部的資訊存入到乙個slice中返回

//如果引數n>0則至多返回n個元素的資訊存入到slice當中

//還有乙個類似的函式是readdir 這個返回的是 目錄中的內容的fileinfo資訊

for

} //遍歷到最後乙個位置

if err1 == io.eof

// if readdirnames returned an error, use it.

if err == nil

if len(names) == 0

}// close directory, because windows won't remove opened directory.

fd.close()

//遞迴結束 當前目錄下位空 刪除當前目錄

// remove directory.

err1 := remove(path)

if err1 == nil || isnotexist(err1)

if err == nil

return err

}

檔案狀態

從檔案中寫入寫出內容

1、在使用f, err := os.open(file_path)開啟檔案之後直接使用f.read() f.write()結合自定義的buffer每次從檔案中讀入/讀出固定的內容

2、使用ioutl的readfile和writefile方法

3、使用bufio採用帶有快取的方式進行讀寫,比如通過info:=bufio.newreader(f)將實現了io.reader的介面的例項載入上來之後,就可以使用info.readline()來每次實現一整行的讀取,直到err資訊為io.eof時,讀取結束

這個blog對三種檔案操作的讀入速度進行了比較,貌似讀取大檔案的時候採用ioutil的時候效率要高些。

package main

import (

"bufio"

"fmt"

"io"

"io/ioutil"

"os"

)func check(e error)

}func main()

}//readline() readbyte() 的用法都是類似 一般都是當err為io.eof的時候

//讀入內容就結束

//感覺實際用的時候 還是通過方式三比較好 粒度正合適 還有多種處理輸入的方式

f.close()

}

//將資料夾中的內容打包成 .gz.tar 檔案

package main

import (

"archive/tar"

"compress/gzip"

"fmt"

"io"

"os"

)//將fi檔案的內容 寫入到 dir 目錄之下 壓縮到tar檔案之中

func filecompress(tw *tar.writer, dir string, fi os.fileinfo)

defer fr.close()

hdr, err := tar.fileinfoheader(fi, "")

hdr.name = fr.name()

if err = tw.writeheader(hdr); err != nil

//bad way

// //資訊頭部 生成tar檔案的時候要先寫入tar結構體

// h := new(tar.header)

// // h.name = fi.name()

// h.size = fi.size()

// h.mode = int64(fi.mode())

// h.modtime = fi.modtime()

// //將資訊頭部的內容寫入

// err = tw.writeheader(h)

// if err != nil

//copy(dst writer,src reader)

_, err = io.copy(tw, fr)

if err != nil

//列印檔案名稱

fmt.println("add the file: " + fi.name())

}//將目錄中的內容遞迴遍歷 寫入tar 檔案中

func dircompress(tw *tar.writer, dir string)

defer dirhandle.close()

fis, err := dirhandle.readdir(0)

//fis的型別為 os.fileinfo

//也可以通過readdirnames來讀入所有子檔案的名稱

//但是這樣 再次判斷是否為檔案的時候 需要通過stat來得到檔案的資訊

//返回的就是os.file的型別

if err != nil

//遍歷檔案列表 每乙個檔案到要寫入乙個新的*tar.header

//var fi os.fileinfo

for _, fi := range fis else }}

//在tardir目錄中建立乙個.tar.gz檔案 存放壓縮之後的檔案

func dirtotar(sourcedir string, tardir string, tarname string)

defer fw.close()

//gzip writer

gw := gzip.newwriter(fw)

defer gw.close()

//tar write

tw := tar.newwriter(gw)

fmt.println("源目錄:", sourcedir)

dircompress(tw, sourcedir)

//通過控制寫入流 也可以控制 目錄結構 比如將當前目錄下的dockerfile檔案單獨寫在最外層

fileinfo, err := os.stat("tarrepo" + "/" + "testdockerfile")

fmt.println("the file name:", fileinfo.name())

if err != nil

//比如這裡將dockerfile放在 tar包中的最外層 會註冊到tar包中的 /tarrepo/testdockerfile 中

filecompress(tw, "tarrepo", fileinfo)

//filecompress(tw, "systempdir/test_testwar_tar/", fileinfo)

fmt.println("tar.gz packaging ok")

}func main()

之前可能也沒有注意 openfile函式與open函式的區別 openfile函式可以指定返回的檔案描述符的許可權,通過o_rdonly、o_wronly、o_rdwr 等等來控制。而open函式在其內部是呼叫openfile函式的,預設的情況是o_rdonly許可權,如果僅僅用open函式返回檔案描述符,之後再對檔案進行寫操作的話,就會返回 bad file descriptor 的錯誤,這個還是應該多留意一下的,細節問題要弄仔細,本質上來說是os中的檔案描述符的問題。

refer to this :

golang 檔案操作

檔案開啟模式 const o rdonly int syscall.o rdonly 唯讀模式開啟檔案 o wronly int syscall.o wronly 只寫模式開啟檔案 o rdwr int syscall.o rdwr 讀寫模式開啟檔案 o create int syscall.o c...

go lang 讀寫檔案操作

參考備份 寫程式離不了檔案操作,這裡總結下 go語言檔案操作。一 建立與開啟 建立檔案函式 func create name string file file,err error func newfile fd int,name string file 具體見官網 開啟檔案函式 func open ...

Golang 檔案讀寫操作

package main import fmt io log os path filepath strconv func main strfile strdir testfile.txt fmt.println file to open is strfile 開啟檔案,如果沒有,那麼建立,設定為讀寫...