1. 程式人生 > 實用技巧 >Go中的檔案操作

Go中的檔案操作

檔案操作

  • 讀取檔案的內容並顯示在終端(帶緩衝區的方式),使用os.Openfile.Close,bufio.NewReader(),reader.ReadString函式和方法。
package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

func main() {
	// 開啟一個檔案
	file, err := os.Open("/home/gocode/src/filedemo/test")
	if err != nil{
		fmt.Println("open file err=",err)
	}

	defer file.Close()  // 要及時關閉檔案控制代碼,否則發有記憶體洩漏

    // 建立一個*Reader,帶緩衝區的,預設的緩衝區為4096
	reader := bufio.NewReader(file)
    // 迴圈讀取檔案內容
	for{
		str, err := reader.ReadString('\n')
		if err == io.EOF{  // io.EOF表示檔案的末尾
			break
		}
		fmt.Print(str)
	}
	fmt.Println("檔案讀取結束")
}
  • 一次將整個檔案讀取到記憶體中,這種方式適用於檔案不大的情況,相關方法和函式(ioutil.ReadFile

    package main
    
    import (
    	"fmt"
    	"io/ioutil"
    )
    
    
    func main() {
    	file := "/home/gocode/src/filedemo/test"
        
        // 使用ioutil.ReadFile一次性讀取
        content, err := ioutil.ReadFile(file)  // 返回值是[]byte{}
    	if err != nil{
    		fmt.Println("read file err:",err)
    	}
    
    	fmt.Println(string(content))  // 需要轉換成字串顯示
       
        // 我們沒有顯示的開啟檔案,所以也不需要顯示的關閉
        // Open()和Close()被封裝到ReadFile 函式內部
    }
    
  • 寫檔案操作

    (1)建立一個新檔案,寫入內容5句“hello Gardon”

    // 寫入時,使用帶快取的*Writer
    package main
    
    import (
    	"bufio"
    	"fmt"
    	"os"
    )
    
    func main() {
    	// 建立一個新檔案,寫入內容5句“hello Gardon”
    	filePath := "test.txt"
    	file, err := os.OpenFile(filePath,os.O_WRONLY|os.O_CREATE,0666)
    	if err != nil{
    		fmt.Println("open file err=",err)
    		return
    	}
    
    	defer file.Close()
    
    	// 寫入內容5句“hello Gardon”
    	str := "hello Gardon\n"
    	// 寫入時,使用帶快取的*Writer
    	writer := bufio.NewWriter(file)
    	for i:=0;i<5;i++{
    		writer.WriteString(str)
    	}
    	// 因為writer是帶快取,因此在呼叫WriteString方法時,其實內容是先寫到快取的
    	writer.Flush()
    }
    

    (2)開啟一個存在的檔案,將原來的內容覆蓋成新的內容10句“你好Christian”

    package main
    
    import (
    	"bufio"
    	"fmt"
    	"os"
    )
    
    func main() {
    	filePath := "test.txt"
    	file,err := os.OpenFile(filePath,os.O_WRONLY|os.O_TRUNC,0666)
    	if err != nil{
    		fmt.Println("open file err:",err)
    		return
    	}
    
    	defer file.Close()
    
    	writer := bufio.NewWriter(file)
    
    	str := "你好Christian\n"
    	for i:=0;i<10;i++{
    		writer.WriteString(str)
    	}
    	writer.Flush()
    }
    

    (3)開啟一個存在的檔案,在原來的內容追加內容“ABC!ENGLISH”

    package main
    
    import (
    	"bufio"
    	"fmt"
    	"os"
    )
    
    func main() {
    	filePath := "test.txt"
    	file,err := os.OpenFile(filePath,os.O_WRONLY|os.O_APPEND,0666)
    	if err != nil{
    		fmt.Println("open file err:",err)
    		return
    	}
    
    	defer file.Close()
    
    	writer := bufio.NewWriter(file)
    
    	str := "ABC!ENGLISH\n"
    	writer.WriteString(str)
    	writer.Flush()
    }
    

    (4)開啟一個存在的檔案,將原來的內容讀出顯示在終端,並追加5句“hello 西安”

    package main
    
    import (
    	"bufio"
    	"fmt"
    	"io"
    	"os"
    )
    
    func main() {
    	filePath := "test.txt"
    	file,err := os.OpenFile(filePath,os.O_RDWR|os.O_APPEND,0666)
    	if err != nil{
    		fmt.Println("open file err:",err)
    		return
    	}
    
    	defer file.Close()
    
    	reader := bufio.NewReader(file)
    	for{
    		str,err:=reader.ReadString('\n')
    		if err == io.EOF{
    			break
    		}
    		fmt.Print(str)
    	}
    	writer := bufio.NewWriter(file)
    
    	str := "hello 西安\n"
    	for i := 0; i<5;i++{
    		writer.WriteString(str)
    	}
    	writer.Flush()
    }
    
    

    (5)將一個檔案中的內容寫入到另外一個檔案中。(判斷要寫入的檔案是否存在)

    package main
    
    import (
    	"fmt"
    	"io/ioutil"
    	"os"
    )
    
    // 判斷檔案以及資料夾是否存在
    func pathExists(path string) (bool,error){
    	_,err := os.Stat(path)
    	if err == nil{
    		return true,nil
    	}
    	if os.IsNotExist(err){
    		return false,nil
    	}
    	return false,err
    }
    
    
    func main() {
    	file1 := "test.txt"
    	file2 := "kkk.txt"
    
    	content, err := ioutil.ReadFile(file1)
    	if err != nil{
    		fmt.Printf("read file err=%v\n",err)
    		return
    	}
    
    	b,_:= pathExists(file2)  // 判斷檔案是否存在,不存在則建立
    	if !b{
    		file,err := os.OpenFile(file2,os.O_RDWR|os.O_CREATE,0666)
    		if err != nil{
    			fmt.Println("create file err:",err)
    			return
    		}
    		defer file.Close()
    	}
    
    	err = ioutil.WriteFile(file2,content,0666)
    	if err != nil{
    		fmt.Println("write file error=",err)
    		return
    	}
    }
    
  • 拷貝檔案

    package main
    
    import (
    	"bufio"
    	"fmt"
    	"io"
    	"os"
    )
    
    func CopyFile(dstFileName, srcFileName string) (written int64,err error){
    	srcFile, err := os.Open(srcFileName)
    	if err != nil{
    		fmt.Println("open file err:",err)
    		return
    	}
    
    	defer srcFile.Close()
    
    	reader := bufio.NewReader(srcFile)
    
    	dstFile, err := os.OpenFile(dstFileName,os.O_RDWR|os.O_CREATE,0666)
    	if err != nil{
    		fmt.Println("open file err:",err)
    		return
    	}
    
    	defer dstFile.Close()
    
    	writer := bufio.NewWriter(dstFile)
    
        return io.Copy(writer,reader)  // 呼叫io.Copy()    
    }
    
    func main() {
    	srcFile := "kkk.txt"
    	dstFile := "kkkk.txt"
    	_, err := CopyFile(dstFile,srcFile)
    	if err != nil{
    		fmt.Println("copy err:",err)
    	}
    }
    
  • 統計字元出現的次數

    // 開啟一個檔案,建立一個Reader,每取一行,就去統計有多少個英文,數字,空格和其他字元
    // 將結果儲存在結構體中
    
    package main
    
    import (
    	"bufio"
    	"fmt"
    	"io"
    	"os"
    )
    
    type Charcount struct{
    	ChCount int
    	NumCount int
    	SpaceCount int
    	OtherCount int
    }
    
    func main() {
    	fileName := "kkk.txt"
    	file,err := os.Open(fileName)
    	if err != nil{
    		fmt.Println("open file err:",err)
    		return
    	}
    	defer file.Close()
    
    	count := Charcount{}
    
    	reader := bufio.NewReader(file)
    	for {
    		str,err := reader.ReadString('\n')
    		if err == io.EOF{
    			break
    		}
    		for _,v:=range str{
    			switch  {
    			case v >= 'a' && v <= 'z':
    				fallthrough
    			case v >= 'A' && v <= 'Z':
    				count.ChCount += 1
    			case v == ' ' || v == '\t':
    				count.SpaceCount +=1
    			case v >= '0' && v <= '9':
    				count.NumCount += 1
    			default:
    				count.OtherCount += 1
    			}
    		}
    	}
    	fmt.Println(count)
    }