Golang 文件讀取和寫入


利用io/ioutil包一次性讀取一個文件的所有內容--ReadFile

package main

import (
	"fmt"
	"io/ioutil"
)

func main() {
	//func ReadFile(filename string) ([]byte, error)
	data, err := ioutil.ReadFile("./connect.go")
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(string(data))
	}
}

  

分多次讀,每次讀取指定長度的文件內容--Read

package main

import (
	"fmt"
	"os"
)

func main() {
	//func Open(name string) (*File, error)
	f, err := os.Open("./connect.go")
	defer f.Close() //注意要關閉文件
	if err != nil {
		panic(err)
	} else {
		buffer := make([]byte, 20)
		//func (f *File) Read(b []byte) (n int, err error)
		//使用Read方法,將文件內容讀入buffer切片中
		length, err := f.Read(buffer)
		if err != nil {
			panic(err)
		} else {
			fmt.Println("讀取了", length, "字節內容")
			fmt.Println(string(buffer))
		}

		//第二次讀取,會接着上一次的位置繼續讀
		length, err = f.Read(buffer)
		if err != nil {
			panic(err)
		} else {
			fmt.Println("讀取了", length, "字節內容")
			fmt.Println(string(buffer))
		}
	}
}

  注意,使用os的Read時,

  1、如果文件的內容長度大於buffer切片的長度,那么,只會讀取文件buffer切片長度的內容,返回的長度就是切片的長度。

  2、如果文件內容小於切片的長度,那么會讀出文件的所有內容,返回的長度就是讀入buffer的實際長度。

  3、如果執行多次從文件中讀取,那么后面一次讀取都會在前面一次讀取結束的位置那里接着繼續讀。

  4、如果

 

從指定位置開始讀--Seek、ReadAt

//設置游標
//func (f *File) Seek(offset int64, whence int) (ret int64, err error)
length, err := f.Seek(3, 1)

  先說第二個參數,可以使0,1,2:

  0表示相對於文件的原點,從文件的開頭往后offset個字符的位置處開始讀。

  1 表示相對於當前偏移量,即已經讀過至少一次了,游標此時不在文件原點,而在其他地方,從那個地方往后offset字符的位置處開始讀。

  2 表示相對於末尾,將文件的末尾作為原點,offset一般為負數,表示從文件末尾往前數offset個字符開始讀。

//從文件的起始位置開始的往后offset位置開始讀
//func (f *File) ReadAt(b []byte, off int64) (n int, err error)
length, err := f.ReadAt(buffer, 5)

  

使用os和io包實現io/ioutil包的ReadFile

func ReadFile(filename string) {
	f, err := os.Open(filename)
	defer f.Close() //注意要關閉文件
	if err != nil {
		panic(err)
	} else {
		buffer := make([]byte, 20)
		//循環讀取
		for {
			length, err := f.Read(buffer)
			//如果錯誤信息是其他類型的,則直接panic
			if err != nil && err != io.EOF {
				panic(err)
			}

			//fmt.Println("讀取了", length, "字節內容")
			if length == 20 {
				fmt.Print(string(buffer))
			} else {
				fmt.Print(string(buffer[0:]))
			}

			//注意,錯誤信息是以io包的EOF時,表示讀取到文件末尾
			if err == io.EOF {
				fmt.Println("讀取完畢")
				break
			}
		}
	}
}

  

使用bufio包輸出每一行的內容,並統計行數

f, err := os.Open("connect.go")
defer f.Close()
if err != nil {
	panic(err)
}
//func NewReader(rd io.Reader) *Reader
reader := bufio.NewReader(f)

totLine := 0

for {
	//func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)
	content, isPrefix, err := reader.ReadLine()

	fmt.Println(string(content), isPrefix, err)

	//當單行的內容超過緩沖區時,isPrefix會被置為真;否則為false;
	if !isPrefix {
		totLine++
	}

	if err == io.EOF {
		fmt.Println("一共有", totLine, "行內容")
		break
	}
}

  

 

創建文件--Create

//創建文件
//func Create(name string) (*File, error)
newFile, err := os.Create("demo.txt")
defer newFile.Close()
if err != nil {
	panic(err)
}

  

獲取文件的信息--Stat

//獲取文件信息
//func Stat(name string) (FileInfo, error)
info, err := os.Stat("test.txt")
if err != nil {
	//func IsNotExist(err error) bool
	if os.IsNotExist(err) {
		panic("文件不存在")
	} else {
		panic(err) //其實err信息中就能看出來上一個判斷是否成立,只是提示有這種判斷方法而已
	}
}
fmt.Println(info.Name(), info.Size(), info.Mode())

  

創建並寫入內容--WriteFile

path := "./demo.txt"
content := "准備寫入的內容"
//func WriteFile(filename string, data []byte, perm os.FileMode) error
err := ioutil.WriteFile(path, []byte(content), 0666)

if err != nil {
	panic(err)
}

//讀取內容
data, err := ioutil.ReadFile(path)
if err != nil {
	panic(err)
}
fmt.Println(string(data))

  

在文件指定位置出寫入內容--WriteAt

path := "test.txt"
f, err := os.Create(path)
defer f.Close()
if err != nil {
	panic(err)
}
//func (f *File) WriteAt(b []byte, off int64) (n int, err error)
length, err := f.WriteAt([]byte("abcdefgh"), 0)
if err != nil {
	panic(err)
}
fmt.Println(length) //8
//abcdefgh

//第二次寫入
length, err = f.WriteAt([]byte("xyz"), 3)
if err != nil {
	panic(err)
}
fmt.Println(length) //3
//abcxyzgh

  

通過buffer writer來寫入文件內容

path := "test.txt"
f, err := os.Create(path)
defer f.Close()
if err != nil {
	panic(err)
}
//func NewWriter(w io.Writer) *Writer bufferWrite := bufio.NewWriter(f) if err != nil { panic(err) } demo := "1234567890" for _, v := range demo { //將數據寫入緩沖區 //func (b *Writer) WriteString(s string) (int, error) bufferWrite.WriteString(string(v)) } data, _ := ioutil.ReadFile(path) fmt.Println(string(data)) //空的內容 //將緩沖區的數據寫入文件 //func (b *Writer) Flush() error bufferWrite.Flush() data, _ = ioutil.ReadFile(path) fmt.Println(string(data)) //1234567890

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM