• go语言文件操作


    文件操作

    字符串处理函数

    字符串在开发中使用频率较高,我们经常需要对字符串进行拆分、判断等操作,可以借助Go标准库中的strings包快速达到处理字符串的目录。除ContainsJoinTrimReplace等我们学过的字符串处理函数之外,以下函数也常常会被用到。

    字符串分割

    func Split(s, sep string) []string
    //功能:把s字符串按照sep分割,返回slice
    参1:s,表示待拆分的字符串
    参2:sep,表示分割符,该参数为string 类型
    返回值:切片,存储拆分好的子串

    示例代码:

    fmt.Printf("%q
    ", strings.Split("a,b,c", ","))
        fmt.Printf("%q
    ", strings.Split("a man a plan a canal panama", "a "))
        fmt.Printf("%q
    ", strings.Split(" xyz ", ""))
        fmt.Printf("%q
    ", 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
    ", 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
    ", 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: 回车、换行。

    Linux: 回车、换行。

    
    

    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
    ")
        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( '
    ' )
                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         // 使用 带分割符的 函数,读取指定数据 ‘
    ’获取一行
    23         buf, err := reader.ReadBytes('
    ')
    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 是一个 目录
    ", dirInfo.Name())
    32         } else {
    33             fmt.Printf("%s is not 目录
    ", 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('
    ')            // 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('
    ')
    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 }
    自己写的思想

     

  • 相关阅读:
    20155208徐子涵 2016-2017-2 《Java程序设计》第8周学习总结
    20155208徐子涵 2016-2017-2 《Java程序设计》第7周学习总结
    20155208徐子涵 2016-2017-2 《Java程序设计》第6周学习总结
    20155208徐子涵 2016-2017-2 《Java程序设计》第5周学习总结
    20155208徐子涵 2016-2017-2 《Java程序设计》第4周学习总结
    20155208徐子涵 2016-2017-2 《Java程序设计》第3周学习总结
    20155208徐子涵 2016-2017-2 《Java程序设计》第2周学习总结
    20155207 2016-2017-2 《Java程序设计》第十周学习总结
    20155207 2016-2017-2 《Java程序设计》第九周学习总结
    20155207 2016-2017-2 《Java程序设计》第八周学习总结
  • 原文地址:https://www.cnblogs.com/qhdsavoki/p/9532052.html
Copyright © 2020-2023  润新知