go語言文件操作


文件操作

字符串處理函數

字符串在開發中使用頻率較高,我們經常需要對字符串進行拆分、判斷等操作,可以借助Go標准庫中的strings包快速達到處理字符串的目錄。除ContainsJoinTrimReplace等我們學過的字符串處理函數之外,以下函數也常常會被用到。

字符串分割

func Split(s, sep string) []string
//功能:把s字符串按照sep分割,返回slice
參1:s,表示待拆分的字符串
參2:sep,表示分割符,該參數為string 類型
返回值:切片,存儲拆分好的子串

示例代碼:

fmt.Printf("%q\n", strings.Split("a,b,c", ","))
    fmt.Printf("%q\n", strings.Split("a man a plan a canal panama", "a "))
    fmt.Printf("%q\n", strings.Split(" xyz ", ""))
    fmt.Printf("%q\n", strings.Split("", "Bernardo O'Higgins"))
    //運行結果:
    //["a" "b" "c"]
    //["" "man " "plan " "canal panama"]
    //[" " "x" "y" "z" " "]
    //[""]

按空格拆分字符串

func Fields(s string) []string
//功能:去除s字符串的空格符,並且按照空格分割,返回slice
參1:s,表示待拆分的字符串
返回值:切片,存儲拆分好的子串

示例代碼:

 fmt.Printf("Fields are: %q", strings.Fields("  foo bar  baz   "))
  //運行結果:Fields are: ["foo" "bar" "baz"]

判斷字符串后綴

func HasSuffix(s, suffix string) bool
功能:判斷s字符串是否有后綴子串suffix
參1:s,表示待判定字符串
參2:suffix,表示前綴子串
返回值:true or false

示例代碼:

fmt.Printf("%v\n", strings.HasSuffix("World Cup.png", ".png"))
    //運行結果:true

判斷字符串前綴

func HasPrefix(s, prefix string) bool
功能:判斷s字符串是否有前綴子串suffix
參1:s,表示待判定字符串
參2:prefix,表示前綴子串
返回值:true or false

示例代碼:

 fmt.Printf("%v\n", strings.HasPrefix("World Cup.png", "world"))
    //運行結果:false

 

文件操作常用API

建立與打開文件

新建文件可以通過如下兩個方法:

func Create(name string) (file *File, err Error)
根據提供的文件名創建新的文件,返回一個文件對象,默認權限是0666的文件,返回的文件對象是可讀寫的。
func main()  {
    f, err := os.Create("C:/itcast/test.txt")
    if err != nil {
        fmt.Println("Create err:", err)
        return
    }
    defer f.Close()

    fmt.Println("create successful")
}
View Code

通過如下兩個方法來打開文件:

func Open(name string) (file *File, err Error)
func main()  {

    f, err := os.Open("C:/itcast/test.txt")
    if err != nil {
        fmt.Println("open err: ", err)
        return
    }
    defer f.Close()

    _, err = f.WriteString("hello world")
    if err != nil {
        fmt.Println("WriteString err: ", err)
        return
    }
    fmt.Println("open successful")
}
View Code

 

Open()是以只讀權限打開文件名為name的文件,得到的文件指針file,只能用來對文件進行“讀”操作。如果我們有“寫”文件的需求,就需要借助Openfile函數來打開了。

 

func OpenFile(name string, flag int, perm uint32) (file *File, err Error)

OpenFile()可以選擇打開name文件的讀寫權限。這個函數有三個默認參數:

1name,表示打開文件的路徑。可使用相對路徑 絕對路徑

參2flg,表示讀寫模式,常見的模式有:

O_RDONLY(只讀模式), O_WRONLY(只寫模式), O_RDWR(可讀可寫模式), O_APPEND(追加模式)。|  O_CREATE (當有此參數,必須指定 參數3)  重要的是如果讀取目錄的話只能指定O_RDONLY模式!!!!

3perm,表權限取值范圍(0-7),表示如下:

0:沒有任何權限

1:執行權限(如果是可執行文件,是可以運行的)

2:寫權限

3: 權限與執行權限

4:讀權限

5: 讀權限與執行權限

6: 讀權限與寫權限

7: 讀權限,寫權限,執行權限

 

func main()  {
    f, err := os.OpenFile("C:/itcast/test.txt", os.O_RDWR | os.O_CREATE, 0600)  // 777--rwx rwx rwx
    if err != nil {
        fmt.Println("OpenFile err: ", err)
        return
    }
    defer f.Close()
    f.WriteString("hello world12345...")

    fmt.Println("open successful")
}
View Code

 

關閉文件函數:

func (f *File) Close() error

寫文件

1.按照字符串寫:

func (file *File) WriteString(s string) (ret int, err Error)
寫入string信息到文件
f.
WriteString
返回實際寫出的字節數

windows: 回車、換行。 \r\n

Linux: 回車、換行。 \n

 
        

2.指定位置寫入

1)Seek():  獲取文件讀寫位置。
       func (f *File) Seek(offset int64, whence int) (ret int64, err error) 
            offset: 矢量。 正數,向文件末尾偏移。負數,向文件開頭偏移
            whence: 偏移的起始位置。
                io.SeekStart : 文件起始位置。
                io.SeekCurrent : 文件當前位置。    
                io.SeekEnd: 文件末尾位置。
            返回值 ret: 從文件起始位置到,讀寫位置的偏移量。                        

2)WriteAt(): 在指定位置寫入數據。, 通常搭配 Seek()用
        func (f *File) WriteAt(b []byte, off int64) (n int, err error)
            b: 待寫入的數據內容
            off:寫入的位置。(通常是 Seek函數的 返回值)    

例子:

package main

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

func main()  {

    f, err := os.Create("./test.txt")
    if err != nil {
        fmt.Println("Create err:", err)
        return
    }
    defer f.Close()

    n, err := f.WriteString("hello world\r\n")
    if err != nil {
        fmt.Println("WriteString err:", err)
        return
    }
    fmt.Println("n = ", n)

    //off, err := f.Seek(5, io.SeekStart)
    off, err := f.Seek(-5, io.SeekEnd)
    if err != nil {
        fmt.Println("Seek err:", err)
        return
    }
    fmt.Println("off:", off)

    n, err = f.WriteAt([]byte("1111"), off)
    if err != nil {
        fmt.Println("WriteAt err:", err)
        return
    }

    fmt.Println("write successful")
}
View Code

 

3.按字節寫--按字節讀 :重要!!!!! ---- 按字節處理文件。既可以處理文本也可以處理二進制文件(.jpg/mp3/avi....)

func (file *File) Read(b []byte) (n int, err Error)

   b: 用來存儲讀到的數據的 緩沖區。

   返回n:實際讀到的 字節數。

 func (file *File) Write(b []byte) (n int, err Error)

   b: 存儲數據的緩沖區,其中的數據即將被寫入文件。。

   返回n:實際寫出的 字節數。

 
 1 func main01()  {
 2     f, err := os.OpenFile("test.txt", os.O_RDWR, 0600)
 3     if err != nil {
 4         fmt.Println("Open err:", err)
 5         return
 6     }
 7     defer f.Close()
 8 
 9     buf := make([]byte, 4096)    // 4k
10 
11     n, err := f.Read(buf)
12     if err != nil {
13         fmt.Println("Read err:", err)
14         return
15     }
16     fmt.Printf("read data:%s", buf[:n])
17 }
18 
19 func main02()  {
20     f, err := os.OpenFile("test.txt", os.O_RDWR, 0600)
21     if err != nil {
22         fmt.Println("Open err:", err)
23         return
24     }
25     defer f.Close()
26 
27     n, err := f.Write([]byte("AAA"))
28     if err != nil {
29         fmt.Println("Write err:", err)
30         return
31     }
32     fmt.Println("n = ", n)
33 }
按照字節讀寫

 

讀文件:bufio

按行讀。----- 處理文本文件。
        1) 獲取一個 reader(自帶緩沖區)
            func NewReader(rd io.Reader) *Reader 
                rd: 成功打開的文件指針。 f
                返回值:Reader (閱讀器,自帶緩沖區)
        2)從 reader 的緩沖區中獲取 指定數據 ReadBytes( '\n' )
            func (b *Reader) ReadBytes(delim byte) ([]byte, error)
                delim :讀取數據的拆分依據。
                返回值:成功獲取到的數據內容。
        通常,會使用 for 來循環調用  ReadBytes, 一直讀到 err == io.EOF 的時候,結束信息。代表文件讀取完畢。
 1 package main
 2 
 3 import (
 4     "os"
 5     "fmt"
 6     "bufio"
 7     "io"
 8 )
 9 
10 func main()  {
11     f, err := os.Open("test.txt")
12     if err != nil {
13         fmt.Println("Open err:", err)
14         return
15     }
16     defer f.Close()
17 
18     // 獲取閱讀器 reader, 自帶緩沖區(用戶緩沖)。
19     reader := bufio.NewReader(f)
20 
21     for {            // 循環讀取文件, 當 err == io.EOF 結束循環
22         // 使用 帶分割符的 函數,讀取指定數據 ‘\n’獲取一行
23         buf, err := reader.ReadBytes('\n')
24         // 成功讀取到的一行數據 保存在 buf中
25         fmt.Printf("buf:%s", buf)
26         if err != nil && err == io.EOF {
27             break
28         }
29     }
30     fmt.Println("文件讀取完畢")
31 }
按行讀文件

讀目錄:

1) 打開目錄  OpenFile
        func OpenFile(name string, flag int, perm FileMode) (*File, error) 
            flag: 只能指定 O_RDONLY
            perm : os.ModeDir        ---> 操作目錄文件
            返回: 操作目錄文件的 指針    
2) 讀取目錄項  Readdir
        func (f *File) Readdir(n int) ([]FileInfo, error)
            n:讀取目錄項的個數。 -1 表全部
            返回值:每一個目錄項 描述信息的(FileInfo) 切片
[]FileInfo 切片
       type FileInfo interface {
        Name() string       // base name of the file
        Size() int64        // length in bytes for regular files; system-dependent for others
        。。。
        IsDir() bool        // abbreviation for Mode().IsDir()
        。。。
      }            
 1 package main
 2 
 3 import (
 4     "os"
 5     "fmt"
 6 )
 7 
 8 func main()  {
 9     var dir string
10     fmt.Print("請輸入一個待判定的目錄:")
11     fmt.Scan(&dir)
12 
13     // 打開目錄
14     f, err := os.OpenFile(dir, os.O_RDONLY, os.ModeDir)
15     if err != nil {
16         fmt.Println("OpenFile err:", err)
17         return
18     }
19     defer f.Close()
20 
21     // 讀取目錄項 -- 將一個目錄下的所有內容, 存入[]FileInfo
22     fileInfo, err := f.Readdir(-1)
23     if err != nil {
24         fmt.Println("Readdir err:", err)
25         return
26     }
27 
28     // 依次取出目錄項
29     for _, dirInfo := range fileInfo {
30         if dirInfo.IsDir() {
31             fmt.Printf("%s 是一個 目錄\n", dirInfo.Name())
32         } else {
33             fmt.Printf("%s is not 目錄\n", dirInfo.Name())
34         }
35     }
36 
37 }
讀取目錄

 

練習例子

大文件拷貝實現:
1
. 只讀打開文件 os.Open --> fr defer close() 2. 創建新文件 os.Create --> fw defer close() 3. for 循環安字節讀取 fr 中的所有數據, 存入 buf 4. 讀多少,寫多少,將buf 中數據寫入 fw 5. 判斷 err == io.EOF 來確認讀到文件末尾。
package main

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

func main()  {
    // 創建 待讀取的文件,和 待寫入的文件
    f_r, err := os.Open("C:/itcast/01-結構體的定義和初始化.avi")
    if err != nil {
        fmt.Println("open err:", err)
        return
    }
    defer f_r.Close()

    f_w, err := os.Create("./test.avi")
    if err != nil {
        fmt.Println("Create err:", err)
        return
    }
    defer f_w.Close()

    buf := make([]byte, 4096)    //創建緩沖區,存儲讀到的數據

    // 循環從 f_r 對應文件中讀取數據,
    for {
        n, err := f_r.Read(buf)
        if err == io.EOF {
            fmt.Println("讀取文件完成")
            break
        }
        if err != nil {
            fmt.Println("Read err:", err)
            return
        }
        // 原封不動寫到 f_w 文件中, 讀多少,寫多少
        n, err = f_w.Write(buf[:n])
        if err != nil {
            fmt.Println("Write err:", err)
            return
        }
    }

    os.OpenFile()
}
View Code

練習1  初級練習

func main() {
    //從用戶給出的目錄中,找出所有的 .jpg 文件
     var path string
     fmt.Scan(&path)
     f,err:=os.OpenFile(path,os.O_RDONLY,os.ModeDir)
     if err!=nil{
         fmt.Println(err)
         return
     }
     fileinfo,err:=f.Readdir(-1)
     if err!=nil{
        fmt.Println("err",err)
        return
    }
     for _,i:=range fileinfo{
        if strings.HasSuffix(i.Name(),"jpg"){
            fmt.Println(i.Name())
        }
    }
從用戶給出的目錄中,找出所有的 .jpg 文件

練習2 中級練習

package main

import (
    "fmt"
    "os"
    "strings"
    "io"
)

func copyMp3ToDir(fileName, path string)  {
    pathName := path + "/" + fileName
    fr, err := os.Open(pathName)                // 打開 源文件
    if err != nil {
        fmt.Println("Open err:", err)
        return
    }
    defer fr.Close()

    fw, err :=os.Create("./" + fileName)        // 打開拷貝的文件
    if err != nil {
        fmt.Println("Create err:", err)
        return
    }
    defer fw.Close()

    // 創建一個用於read 存儲數據的 buf
    buf := make([]byte, 4096)

    // 循環從 fr 中讀取數據, 原封不動 寫到 fw中
    for {
        n, err := fr.Read(buf)
        if n == 0 {
            fmt.Println("文件拷貝完畢")
            break
        }
        if err != nil && err != io.EOF {
            fmt.Println("err:", err)
        }
        fw.Write(buf[:n])      // 讀多少,寫多少
    }

}

func main()  {
    // 請用戶指定 目錄
    var path string
    fmt.Print("請輸入目錄位置:")
    fmt.Scan(&path)

    // 打開指定目錄位置
    dir_fp, err := os.OpenFile(path, os.O_RDONLY, os.ModeDir)
    if err != nil {
        fmt.Println("Openfile err:", err)
        return
    }
    defer dir_fp.Close()

    // 讀取目錄項
    dirsInfo, err := dir_fp.Readdir(-1)
    if err != nil {
        fmt.Println("Readdir err:", err)
        return
    }
    // 從目錄項[] 中提取每一個目錄項
    for _, dir := range dirsInfo {
        fileName := dir.Name()
        // 根據后綴名,篩選文件
        if strings.HasSuffix(fileName, ".mp3") {

            // 將該文件 copy 至指定目錄
            copyMp3ToDir(fileName, path)
            //fmt.Println("mp3文件有:", fileName)
        }
    }
}
從用戶給出的目錄中,拷貝 .mp3文件到指定目錄中。
    //2.從用戶給出的目錄中,拷貝 .mp3文件到指定目錄中。
    args:=os.Args
    f1,err:=os.OpenFile(args[1],os.O_RDONLY,os.ModeDir)
    if err!=nil{
        fmt.Println(err)
        return
    }
    fmt.Println(args[1],args[2])
    fileinfo,err:=f1.Readdir(-1)
    if err!=nil {
        fmt.Println(err)
    }
    for _,name:=range fileinfo{
        //fmt.Println(name)
        if strings.HasSuffix(name.Name(),".mp3"){
            fmt.Println(name.Name())
            copyfile(args[1]+"/"+name.Name(),args[2]+"/"+name.Name())
        }
    }
    defer f1.Close()
}
func copyfile(dst,src string){
    buf:=make([]byte,4096)
    f1, err := os.OpenFile(dst, os.O_RDONLY, 0666)
    if err != nil {
        fmt.Println(err)
        return
    }
    fw, err := os.Create(src)
    if err != nil {
        fmt.Println(err)
        return
    }
    for {
        n, err := f1.Read(buf)
        if err != nil || err ==io.EOF{
            fmt.Println(err)
            break
        }
        fw.Write(buf[:n])
    }
        defer fw.Close()
自己寫的

練習3  高級練習

 1 package main
 2 
 3 import (
 4     "os"
 5     "fmt"
 6     "strings"
 7     "bufio"
 8     "io"
 9 )
10 
11 func countLove(fileName, path string) int {
12     // 打開文件,txt
13     f, err := os.Open(path + "/" + fileName)
14     if err != nil {
15         fmt.Println("Open err:", err)
16         return -1
17     }
18     defer f.Close()
19 
20     // 1 創建 reader
21     reader := bufio.NewReader(f)
22     var counter int = 0
23 
24     // for 循環 按行讀取文件,--- this is a  test for love  --》[]string
25     for {
26         // 2 指定分隔符,按行提取數據
27         buf, err := reader.ReadBytes('\n')            // buf中保存讀到的一行數據
28         if err != nil && err == io.EOF {
29             break
30         }
31         if err != nil {
32             fmt.Println("ReadBytes err:", err)
33             return -1
34         }
35         // 將一行數據中的所有單詞 拆分
36         words := strings.Fields(string(buf))
37         for _, word := range words {
38             if word == "love" {
39                 counter++    // 統計 個數。
40             }
41         }
42     }
43     fmt.Println("counter:", counter)
44 
45     return counter
46 }
47 
48 func main()  {
49 
50     // 測試統計 函數是否生效
51     //countLove("test.txt", "C:/itcast/test2")
52 
53     // 請用戶指定 目錄
54     var path string
55     fmt.Print("請輸入目錄位置:")
56     fmt.Scan(&path)
57 
58     // 打開指定目錄位置
59     dir_fp, err := os.OpenFile(path, os.O_RDONLY, os.ModeDir)
60     if err != nil {
61         fmt.Println("Openfile err:", err)
62         return
63     }
64     defer dir_fp.Close()
65 
66     // 統計目錄下所有 txt 文件的 love 個數
67     var allLove int = 0
68 
69     // 讀取目錄項
70     dirsInfo, err := dir_fp.Readdir(-1)
71     if err != nil {
72         fmt.Println("Readdir err:", err)
73         return
74     }
75     // 從目錄項[] 中提取每一個目錄項
76     for _, dir := range dirsInfo {
77         fileName := dir.Name()
78         // 根據后綴名,篩選文件
79         if strings.HasSuffix(fileName, ".txt") {
80             // 打開文件, 統計 該文件中有多少個 “love”
81             allLove += countLove(fileName, path)
82         }
83     }
84     fmt.Println("指定的目錄中,一共包含 love 個數:", allLove)
85 }
統計指定目錄下,所有.txt文件中,“Love”這個單詞 出現的次數
 1 package main
 2 
 3 import (
 4     "os"
 5     "fmt"
 6     "strings"
 7     "bufio"
 8     "io"
 9 )
10 
11 func main() {
12     //統計指定目錄下,所有.txt文件中,“Love”這個單詞 出現的次數。
13     args:=os.Args
14     fdir,err:=os.OpenFile(args[1],os.O_RDONLY,os.ModeDir)
15     if err!=nil{
16         fmt.Println(err)
17         return
18     }
19     fileinof,err:=fdir.Readdir(-1)
20     var txt []string
21     for _,info:=range fileinof{
22 
23         if strings.HasSuffix(info.Name(),".txt"){
24             fmt.Println(info.Name())
25             txt=append(txt, info.Name())
26         }
27     }
28     for _,v:=range txt{
29         prisetxt("love","D:/111/"+v)
30     }
31 }
32 //func dir(){}
33 func prisetxt(s string,txt string){
34 
35     f1,err:=os.Open(txt)
36     if err!=nil{
37         fmt.Println(err)
38     }
39     reader:=bufio.NewReader(f1)
40     //conster :=0
41     for {
42         bytess, err := reader.ReadBytes('\n')
43         fmt.Println(string(bytess))
44         con:=strings.Split(string(bytess),"love")
45         fmt.Println(len(con)-1)
46         if err != nil || err == io.EOF {
47             fmt.Println(err)
48             break
49         }
50 
51     }
52     defer f1.Close()
53     //fmt.Println(conster)
54 
55 }
自己寫的思想

 

 


免責聲明!

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



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