獲取文件列表路徑
package _caseimport ("fmt""log""os""strings"
)// 獲取文件路徑
// 源文件目錄
const sourceDir = "file/"// 目標文件目錄
const destDir = "det_file/"// 拿到目錄下完整的路徑
func geFiles(dir string) []string {//讀取目錄fs, err := os.ReadDir(dir)if err != nil {log.Fatal()}//定義一個list接收我們的文件路徑list := make([]string, 0)for _, f := range fs {//如果是個空的文件夾就繼續if f.IsDir() {continue}//去掉字符串s中首部以及尾部與字符串cutset中每個相匹配的字符 //Name返回條目所描述的文件(或子目錄)的名稱。fullName := strings.Trim(dir, "/") + "/" + f.Name()list = append(list, fullName)fmt.Println(list)}return list
}
文件目錄拷貝
package _case//文件復制
import ("io""log""os""path"
)// 拷貝目錄到目錄
func Copy() {list := geFiles(sourceDir)for _, f := range list {//Split 函數將路徑從最后一個斜杠后面位置分隔為兩個部分( dir 和 file )并返回。如果路徑中沒有斜杠,//函數返回值 dir 會設為空字符串, file 會設為 path 。兩個返回值滿足 path == dir+file_, name := path.Split(f) //把文件名輸出destFileName := destDir + "copy/" + name //這個name是把文件名放在了目標文件加后//fmt.Println(destFileName)//復制文件CopyFile(f, destFileName)}
}func CopyFile(srcName, destName string) (int64, error) {//打開源文件src, err := os.Open(srcName)if err != nil {log.Fatal(err)}defer src.Close()//打開目標文件 可讀可寫可創建det, err := os.OpenFile(destName, os.O_CREATE|os.O_WRONLY, 0644)if err != nil {log.Fatal(err)}defer det.Close()return io.Copy(det, src)
}
一次性讀取文件內容并寫入
讀取文件內容并寫入
package _caseimport ("log""os""path"
)// 一次性讀取文件內容并寫入
func ReadWriteFiles() {//獲取源文件路徑list := geFiles(sourceDir)for _, f := range list {bytes, err := os.ReadFile(f)if err != nil {log.Fatal(err)}_, name := path.Split(f)destname := destDir + "normal/" + nameerr1 := os.WriteFile(destname, bytes, 0644)if err1 != nil {log.Fatal(err1)}}
}
分片讀取文件并寫入
package _caseimport ("io""log""os""path"
)// 適用大文件
// 分片讀取文件內容分布寫入新文件
func OneSideReadWriteToDest() {list := geFiles(sourceDir)for _, f := range list {_, name := path.Split(f)destFileName := destDir + "one_side/" + name//文件寫入OneSideReadWrite(f, destFileName)}
}
func OneSideReadWrite(srcName, destName string) {src, err := os.Open(srcName)if err != nil {log.Fatal("1", err)}defer src.Close()dst, err := os.OpenFile(destName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)if err != nil {log.Fatal("2", err)}defer dst.Close()//切片 文件最大的限度buf := make([]byte, 1024)for {n, err := src.Read(buf)if err != nil && err != io.EOF { //如果沒有這個io.EOF的話就會報錯log.Fatal("3...", err)}if n == 0 {break}dst.Write(buf[:n])}}
一次性讀取按行拆分
const README = "README.MD"
func ReadLine1() {fileHeader, err := os.OpenFile(README, os.O_RDONLY, 0444)if err != nil {log.Fatal(err)}defer fileHeader.Close()//將文件一次性讀取出來bytes, err := io.ReadAll(fileHeader)if err != nil {log.Fatal(err)}list := strings.Split(string(bytes), "\n")for _, i := range list {fmt.Println(i)}}
按行讀取用于大文件
bufio 通過對io模塊的封裝提供了數據的緩沖功能,能一定程度減少大文件數據塊帶來的開銷。當發起讀寫操作時,會嘗試從緩沖區讀取數據,緩沖區沒有數據后,才會從數據源去讀取緩沖區大小默認為4k
func ReadLine2() {fileHeader, err := os.OpenFile(README, os.O_RDONLY, 0444)if err != nil {log.Fatal(err)}defer fileHeader.Close()reader := bufio.NewReader(fileHeader)for true {//加上分隔符line, err := reader.ReadString('\n')if err == io.EOF {break}fmt.Print(line)}
}func ReadLine3() {fileHeader, err := os.OpenFile(README, os.O_RDONLY, 0444)if err != nil {log.Fatal(err)}defer fileHeader.Close()scanner := bufio.NewScanner(fileHeader)for scanner.Scan() {line := scanner.Text()fmt.Println(line)}
}
Scanner按行讀取文件
先使用 NewScanner() 創建 Scanner 對象。然后在 for 循環中,使用 Scanner 的 Scan() 方法讀取文件的每一行,在使用 Text() 方法獲取每一行的內容。最后,將獲取到的行追加到字符串切片中。
func ReadLines(path string) ([]string, error) {file, err := os.Open(path)if err != nil {return nil, err}defer file.Close()var lines []stringscanner := bufio.NewScanner(file)for scanner.Scan() {lines = append(lines, scanner.Text())}return lines, scanner.Err()
}
Reader 讀取每一行
使用 bufio.Reader 時,需用 ReadBytes() 或 ReadString() 方法來讀取每一行。使用 NewReader() 函數創建一個 Reader 對象。在 for 循環中,我們使用 ReadString() 函數讀取每一行的內容,并將其追加到字符串切片中。
func ReadLinesV2(path string) ([]string, error) {file, err := os.Open(path)if err != nil {return nil, err}defer file.Close()var lines []stringreader := bufio.NewReader(file)for {// ReadString reads until the first occurrence of delim in the input,// returning a string containing the data up to and including the delimiter.line, err := reader.ReadString('\n')if err == io.EOF {lines = append(lines, line)break}if err != nil {return lines, err}lines = append(lines, line[:len(line)-1])}return lines, nil
}
ReadLine 按行讀取
使用 bufio.Reader 逐行讀取文件時,除使用 ReadBytes() 或 ReadString() 方法,可以用 ReadLine() 函數
func ReadLinesV3(path string) ([]string, error) {f, err := os.Open(path)if err != nil {return nil, err}defer f.Close()var lines []stringr := bufio.NewReader(f)for {// ReadLine is a low-level line-reading primitive.// Most callers should use ReadBytes('\n') or ReadString('\n') instead or use a Scanner.bytes, _, err := r.ReadLine()if err == io.EOF {break}if err != nil {return lines, err}lines = append(lines, string(bytes))}return lines, nil
}
使用 bufio.Reader 的 ReadLine() 方法可以讀取一行數據,但是需要注意它的返回值。ReadLine() 函數的返回值包括三個部分:讀取到的數據、是否讀取完整一行以及錯誤信息。如果讀取到的數據超出了緩存區的大小,它會返回一個錯誤信息,而不是完整的一行數據。
因此,如果讀取的一行數據的長度超過了緩存區的大小,ReadLine() 函數將無法讀取到完整的一行數據。為了避免這種情況的發生,我們可以通過設置緩存區的大小來解決。
ReadLine 是一個低級的行讀取原語。大多數調用者應該使用 ReadBytes(‘\n’) 或 ReadString(‘\n’),或者使用 Scanner。