檔案讀取
os.File
封裝了檔案相關操作
type File
File代表一個開啟的檔案對象
func Create(name string) (file *File, err error)
- Create採用模式0666(任何人都可以讀寫,不可執行)建立一個名為name的檔案,
- 如果檔案已存在會截斷它(為空白檔案).
- 如果成功,返回的檔案對象可用於I/O;對應的檔案描述符具有O_RDWR模式。
- 如果出錯,錯誤底層類型是*PathError。
func Open(name string) (file *File, err error)
Open開啟一個檔案用於讀取。如果操作成功,返回的檔案對象的方法可用於讀取資料;
對應的檔案描述符具有O_RDONLY模式。如果出錯,錯誤底層類型是*PathError。
func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
- OpenFile是一個更一般性的檔案開啟函數,大多數調用者都應用Open或Create代替本函數。
- 它會使用指定的選項(如O_RDONLY等)、指定的模式(如0666等)開啟指定名稱的檔案。
- 如果操作成功,返回的檔案對象可用於I/O。
- 如果出錯,錯誤底層類型是*PathError。
func NewFile(fd uintptr, name string) *File
NewFile使用給出的Unix檔案描述符和名稱建立一個檔案
func Pipe() (r *File, w *File, err error)
Pipe返回一對關聯的檔案對象。從r的讀取將返回寫入w的資料。
本函數會返回兩個檔案對象和可能的錯誤。
func (f *File) Name() string
Name方法返回(提供給Open/Create等方法的) 檔案名稱。
func (f *File) Stat() (fi FileInfo, err errror)
Stat返回描述檔案f的FileInfo類型值。如果出錯,錯誤底怪類型是*PathError。
func (f *File) Fd() uintptr
Fd返回與檔案f對應的整數類型的Unix檔案描述符。
func (f *File) Chdir() error
Chdir將當前工作目錄修改為f,f必須是一個目錄。如果出錯,錯誤底層類型是*PathError
func (f *File) Chmod(mode FileMode) error
Chmod修改檔案的模式。如果出錯,錯誤底層類型是*PathError
func (f *File) Chown(uid, git int) error
Chown修改檔案的使用者ID和組ID。如果出錯,錯誤底怪類型是*PathError。
func (f *File) Readdir(n int) (fi []FileInfo, err error)
- Readdir讀取目錄f的內容,返回一個有n個成員的[]FileInfo,這些FileInfo是被Lstat返回的,採用目錄順序。
- 對本函數的下一次調用會返回上一次調用剩餘未讀取的內容的資訊。
- 如果n>0,Readdir函數會返回一個最多n個成員的切片。
- 這時,如果Readdir返回一個空切片,它會返回一個非nil的錯誤說明原因。
- 如果到達了目錄f的結尾,傳回值err會是io.EOF.
- 如果n<=0, Readdir函數返回目錄中剩餘所有檔案對象的FileInfo構成的切片。
- 此時,如果Readdir調用成功(讀取所有內容直到結尾),它會返回該切片和nil的錯誤值。
- 如果在到達結尾前遇到錯誤,會返回之前成功讀取的FileInfo構成的切片和該錯誤。
func (f *File) Readdirnames(n int) (names []string, err error)
- Readdir讀取目錄f的內容,返回一個有n個成員的[]string,切片成員為目錄中檔案對象的名字,採用目錄順序。
- 對本函數的下一次調用會返回上一次調用剩餘未讀取的內容的資訊.
- 如果n>0,Readdir函數會返回一個最多n個成員的切片。這時,如果Readdir返回一個空切片,它會返回一個非nil的錯誤說明原因。
- 如果到達了目錄f的結尾,傳回值err會不io.EOF。
- 如果n<=0,Readdir函數返回目錄中剩餘所有檔案對象的名字構成的切片。此時,如果Readdir調用成功(讀取所有內容直到結尾),它會返回該切片和nil的錯誤值。
- 如果在到達結尾前遇到錯誤,會返回之前成功讀取的名字構成的切片和該錯誤。
func (f *File) Truncate(size int64) error
Truncate改變檔案的大小,它不會改變I/O的當前位置。如果截斷檔案,多出的部分就會被丟棄。如果出錯,錯誤底層類型是*PathError。
func (f *File) Read(b []byte) (n int, err error)
Read方法從f中讀取最多len(b)位元組資料並寫入b。它返回讀取的位元組數和可能遇到的任何錯誤。檔案終止標誌是讀取0個位元組且傳回值err為io.EOF。
func (f *File) ReadAt(b []byte, off int64) (n int, err error)
ReadAt從指定的位置(相對於檔案開始位置) 讀取len(b)位元組資料並寫入b。
它返回讀取的位元組數和可能遇到的任何錯誤。當n<len(b)時,本方法總是會返回錯誤;如果是因為到達檔案結尾,傳回值err會是io.EOF.
func (f *File) Write(b []byte) (n int, err error)
Write向檔案中寫入len(b)位元組資料。它返回寫入的位元組數和可能遇到的任何錯誤。如果傳回值n != len(b), 本方法會返回一個非nil的錯誤。
func (f *File) WriteString(s string) (ret int, err error)
WriteString類似Write,但接受一個字串參數.
func (f *File) WriteAt (b []byte, off int64) (n int,err error)
WriteAt在指定的位置(相對於檔案開始位置) 寫入len(b)位元組資料。它返回寫入的位元組數和可能遇到的任何錯誤。如果傳回值n != len(b),本方法會返回一個非nil的錯誤。
func (f *File) Seek(offset int64, whence int) (ret int64,err error)
Seek設定下一次讀/寫的位置。offset為相對位移量,而whence決定相對位置: 0為相對檔案開頭,1為相對當前位置,2為相對檔案結尾。
它返回新的位移量(相對開頭)和可能的錯誤.
func (f *File) Sync() (err error)
Sync遞交檔案的當前內容進行穩定的儲存。一般來說,這表示將檔案系統的最近寫入的資料在記憶體中的拷貝重新整理到硬碟中穩定儲存。
func (f *File) Close() error
Close關閉檔案f,使檔案不能用於讀寫。它返回可能出現的錯誤。
讀寫參數
檔案開啟模式:
const ( O_RDONLY int = syscall.O_RDONLY // 唯讀模式開啟檔案 O_WRONLY int = syscall.O_WRONLY // 唯寫模式開啟檔案 O_RDWR int = syscal.O_RDWR // 讀寫入模式開啟檔案 O_APPEND int = syscall.O_APPEND // 寫操作時將資料附加到檔案尾部 O_CREATE int = syscall.O_CREAT // 如果不存在將建立一個新檔案 O_EXCL int = syscall.O_EXCL // 開啟檔案用於同步I/O O_SYNC int = syscall.O_SYNC // 開啟檔案用於同步I/O O_TRUNC int = syscall.O_TRUNC // 如果可能,開啟時清空檔案)
讀取例子
os.Open || os.OpenFile
pacakge mainimport ( "bufio" "fmt" "os")func main() { // file, err := os.Open("/tmp/test") file, err := os.OpenFile("/tmp/test",os.O_CREATE|os.O_WRONLY,0666) if err != nil { fmt.Println("Open file error:",err) return } defer file.Close() // 關閉檔案 reader := bufio.NewReader(file) //帶緩衝區的讀寫 for { str, err := reader.ReadString('\n') //迴圈讀取一行 if err != nil { fmt.Println("read string failed, err: ",err) return } fmt.Println("read string is %s: ",str) }}
readline
一行一行的讀取檔案內容
package mainimport ( "bufio" "fmt" "io" "os")func main() { file, err := os.Open("/tmp/test.log") if err != nil { fmt.Println(err) return } defer file.Close() reader := bufio.NewReader(file) var line []byte for { data, prefix, err := reader.ReadLine() if err == io.EOF { break } line = append(line, data...) if !prefix { fmt.Printf("data:%s\n",string(line)) line = line[:] } }}
讀取整個檔案例子
"io/ioutil"包實現了讀取整個檔案功能
package mainimport ( "fmt" "os" "io/ioutil")func main() { fileName := "/tmp/test" file, err := os.OpenFile(fileName, os.O_CREATE|os.O_RDWR, 0666) if err != nil { fmt.Println("Open file error: ",err) return } defer file.Close() buf, err := ioutil.ReadAll(file) // buf, err := ioutil.ReadFile(fileName) if err != nil { fmt.Fprintf(os.Stderr, "File Error: %s\n",err) return } fmt.Printf("%s\n",string(buf))}
讀取壓縮檔
"compress/*" 包實現壓縮檔功能
"compress/gzip" 包實現了gzip格式壓縮檔的讀寫
package mainimport ( "bufio" "compress/gzip" "fmt" "os")func main() { fileName := "/tmp/test.log.gz" var r *bufio.Reader fi, err := os.Open(fileName) if err != nil { fmt.Println("error",err) os.Exit(1) } fz, err := gzip.NewReader(fi) if err != nil { fmt.Println("error",err) return } r = bufio.NewReader(fz) for { line, err := r.ReadString('\n') if err != nil { fmt.Println("Done reading file") return } fmt.Println(line) }}
檔案寫入
file.WriteString || file.Write
package mainimport ( "fmt" "os")func main() { fileName := "/tmp/test_write" file, err := os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY, 0644) if err != nil { fmt.Println("error",err) os.Exit(1) } defer file.Close() fileString := "Today very happy." file.Seek(0,2) // 最後增加 file.WriteString(fileString) // file.Write([]byte(fileString))}
bufio.Writer.WriteString
帶緩衝的寫,最後要將緩衝中的資料寫入下層的io.Writer介面(Flush方法)
package mainimport ( "bufio" "fmt" "os")func main() { fileName := "/tmp/test_write" file, err := os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY, 0755) if err != nil { fmt.Println("error",err) os.Exit(1) } defer file.Close() fileWrite := bufio.NewWriter(file) fileString := "good.\n" for i := 0; i < 10; i++ { fileWrite.WriteString(fileString) } fileWrite.Flush()}
拷貝檔案
從一個檔案拷貝到另一個檔案
package mainimport ( "fmt" "io" "os")func CopyFile(dstName, srcName string) (writeen int64,err error) { src, err := os.Open(dstName) if err != nil { fmt.Println(err) return } defer src.Close() dst, err := os.OpenFile(srcName, os.O_CREATE|os.O_WRONLY, 0644) if err != nil { fmt.Println(err) return } defer dst.Close() return io.Copy(dst, src)}func main() { CopyFile("/tmp/test","/tmp/test_copy1") fmt.Println("copy done.")}
判斷檔案或檔案夾是否存在
func PathExists(path string) (bool, error) { /* 判斷檔案或目錄是否存在 如果返回的錯誤為nil,說明檔案或目錄存在 如果返回的錯誤類型使用os.IsNotExits()判斷為true,說明檔案或檔案夾不存在 如果返回的錯誤為其它類型,則不確定是否存在 */ _, err := os.Stat(path) if err == nil { return true,nil } if os.InNotExist(err) { return false,nil } return false, err}