美文网首页go
Go语言文件操作

Go语言文件操作

作者: 羋学僧 | 来源:发表于2022-01-04 17:42 被阅读0次

    本文主要介绍了Go语言中文件读写的相关操作。

    文件是什么?

    计算机中的文件是存储在外部介质(通常是磁盘)上的数据集合,文件分为文本文件和二进制文件。

    打开和关闭文件

    os.Open()函数能够打开一个文件,返回一个*File和一个err。对得到的文件实例调用close()方法能够关闭文件。

    package main
    
    import (
        "fmt"
        "os"
    )
    
    func main() {
        // 只读方式打开当前目录下的main.go文件
        file, err := os.Open("./main.go")
        if err != nil {
            fmt.Println("open file failed!, err:", err)
            return
        }
        // 关闭文件
        file.Close()
    }
    

    为了防止文件忘记关闭,我们通常使用defer注册文件关闭语句。

    读取文件

    file.Read()

    基本使用

    Read方法定义如下:

    func (f *File) Read(b []byte) (n int, err error)
    

    它接收一个字节切片,返回读取的字节数和可能的具体错误,读到文件末尾时会返回0io.EOF。 举个例子:

    func main() {
        // 只读方式打开当前目录下的main.go文件
        file, err := os.Open("./main.go")
        if err != nil {
            fmt.Println("open file failed!, err:", err)
            return
        }
        defer file.Close()
        // 使用Read方法读取数据
        var tmp = make([]byte, 128)
        n, err := file.Read(tmp)
        if err == io.EOF {
            fmt.Println("文件读完了")
            return
        }
        if err != nil {
            fmt.Println("read file failed, err:", err)
            return
        }
        fmt.Printf("读取了%d字节数据\n", n)
        fmt.Println(string(tmp[:n]))
    }
    

    循环读取

    使用for循环读取文件中的所有数据。

    func main() {
        // 只读方式打开当前目录下的main.go文件
        file, err := os.Open("./main.go")
        if err != nil {
            fmt.Println("open file failed!, err:", err)
            return
        }
        defer file.Close()
        // 循环读取文件
        var content []byte
        var tmp = make([]byte, 128)
        for {
            n, err := file.Read(tmp)
            if err == io.EOF {
                fmt.Println("文件读完了")
                break
            }
            if err != nil {
                fmt.Println("read file failed, err:", err)
                return
            }
            content = append(content, tmp[:n]...)
        }
        fmt.Println(string(content))
    }
    

    bufio读取文件

    bufio是在file的基础上封装了一层API,支持更多的功能。

    package main
    
    import (
        "bufio"
        "fmt"
        "io"
        "os"
    )
    
    // bufio按行读取示例
    func main() {
        file, err := os.Open("./xx.txt")
        if err != nil {
            fmt.Println("open file failed, err:", err)
            return
        }
        defer file.Close()
        reader := bufio.NewReader(file)
        for {
            line, err := reader.ReadString('\n') //注意是字符
            if err == io.EOF {
                if len(line) != 0 {
                    fmt.Println(line)
                }
                fmt.Println("文件读完了")
                break
            }
            if err != nil {
                fmt.Println("read file failed, err:", err)
                return
            }
            fmt.Print(line)
        }
    }
    

    ioutil读取整个文件

    io/ioutil包的ReadFile方法能够读取完整的文件,只需要将文件名作为参数传入。

    package main
    
    import (
        "fmt"
        "io/ioutil"
    )
    
    // ioutil.ReadFile读取整个文件
    func main() {
        content, err := ioutil.ReadFile("./main.go")
        if err != nil {
            fmt.Println("read file failed, err:", err)
            return
        }
        fmt.Println(string(content))
    }
    

    文件写入操作

    os.OpenFile()函数能够以指定模式打开文件,从而实现文件写入相关功能。

    func OpenFile(name string, flag int, perm FileMode) (*File, error) {
        ...
    }
    

    其中:

    name:要打开的文件名 flag:打开文件的模式。 模式有以下几种:

    模式 含义
    os.O_WRONLY 只写
    os.O_CREATE 创建文件
    os.O_RDONLY 只读
    os.O_RDWR 读写
    os.O_TRUNC 清空
    os.O_APPEND 追加

    perm:文件权限,一个八进制数。r(读)04,w(写)02,x(执行)01。

    Write和WriteString

    func main() {
        file, err := os.OpenFile("xx.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
        if err != nil {
            fmt.Println("open file failed, err:", err)
            return
        }
        defer file.Close()
        str := "hello 上海"
        file.Write([]byte(str))       //写入字节切片数据
        file.WriteString("hello 小王子") //直接写入字符串数据
    }
    

    bufio.NewWriter

    func main() {
        file, err := os.OpenFile("xx.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
        if err != nil {
            fmt.Println("open file failed, err:", err)
            return
        }
        defer file.Close()
        writer := bufio.NewWriter(file)
        for i := 0; i < 10; i++ {
            writer.WriteString("hello上海\n") //将数据先写入缓存
        }
        writer.Flush() //将缓存中的内容写入文件
    }
    

    示例

    
    package main
    
    import (
        "bufio"
        "fmt"
        "os"
    )
    
    func useScan() {
        var s string
        fmt.Print("请输入内容:")
        fmt.Scanln(&s)
        fmt.Printf("你输入的内容是:%s\n", s)
    }
    
    func useBufio() {
        var s string
        reader := bufio.NewReader(os.Stdin)
        fmt.Print("请输入内容:")
        s, _ = reader.ReadString('\n')
        fmt.Printf("你输入的内容是:%s\n", s)
    }
    
    func main() {
        //useScan()
        useBufio()
    }
    
    

    ioutil.WriteFile

    func main() {
        str := "hello 上海"
        err := ioutil.WriteFile("./xx.txt", []byte(str), 0666)
        if err != nil {
            fmt.Println("write file failed, err:", err)
            return
        }
    }
    

    在文件中间插入内容

    package main
    
    import (
        "fmt"
        "io"
        "os"
    )
    
    func middleInsert() {
        // 打开要操作的文件
        fileObj, err := os.OpenFile("./mi.txt",os.O_RDWR,0644)
        if err != nil {
            fmt.Printf("open file failed, err:%v\n", err)
            return
        }
        // 借助临时文件
        tmpFile, err := os.OpenFile("./mi.tmp", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
        if err != nil {
            fmt.Printf("create tmp file failed, err:%v\n", err)
            return
        }
        // 读取源文件写入临时文件
        var ret [1]byte
        n, err := fileObj.Read(ret[:])
        if err != nil {
            fmt.Printf("read from file failed, err:%v\n", err)
            return
        }
        // 写入临时文件
        tmpFile.Write(ret[:n])
        // 再写入要插入的内容
        var s []byte
        s = []byte{'w'}
        tmpFile.Write(s)
        // 紧接着把源文件后续的内容写入临时文件
        var x [1024]byte
        for {
            n, err := fileObj.Read(x[:])
            if err == io.EOF {
                tmpFile.Write(x[:n])
                break
            }
            if err != nil {
                fmt.Printf("read from file failed, err:%v\n", err)
                return
            }
            tmpFile.Write(x[:n])
        }
        // 源文件后续的也写入了临时文件,关闭源文件
        fileObj.Close()
        tmpFile.Close()
        os.Rename("./mi.tmp","./mi.txt")
    
        
    
    
    }
    
    func main() {
        middleInsert()
    }
    

    相关文章

      网友评论

        本文标题:Go语言文件操作

        本文链接:https://www.haomeiwen.com/subject/rptccrtx.html