Go语言IO输入输出底层原理及文件操作API

 更新时间:2023年01月08日 10:41:54   作者:夏沫的梦  
这篇文章主要为大家介绍了Go语言IO输入输出底层原理及文件操作API示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

1.输入输出的底层原理

终端其实是一个文件,相关实例如下:

  • os.Stdin:标准输入的文件实例,类型为*File
  • os.Stdout:标准输出的文件实例,类型为*File
  • os.Stderr:标准错误输出的文件实例,类型为*File

以文件的方式操作终端:

package main
import "os"
func main() {
    var buf [16]byte
    os.Stdin.Read(buf[:])
    os.Stdin.WriteString(string(buf[:]))
}

2. 文件操作相关API

  • func Create(name string) (file *File, err Error) 根据提供的文件名创建新的文件,返回一个文件对象,默认权限是0666
  • func NewFile(fd uintptr, name string) *File 根据文件描述符创建相应的文件,返回一个文件对象
  • func Open(name string) (file *File, err Error) 只读方式打开一个名称为name的文件
  • func OpenFile(name string, flag int, perm uint32) (file *File, err Error) 打开名称为name的文件,flag是打开的方式,只读、读写等,perm是权限
  • func (file *File) Write(b []byte) (n int, err Error) 写入byte类型的信息到文件
  • func (file *File) WriteAt(b []byte, off int64) (n int, err Error) 在指定位置开始写入byte类型的信息
  • func (file *File) WriteString(s string) (ret int, err Error) 写入string信息到文件
  • func (file *File) Read(b []byte) (n int, err Error) 读取数据到b中
  • func (file *File) ReadAt(b []byte, off int64) (n int, err Error) 从off开始读取数据到b中
  • func Remove(name string) Error 删除文件名为name的文件

3. 打开和关闭文件

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()
}

4. 写文件

package main
import (
    "fmt"
    "os"
)
func main() {
    // 新建文件
    file, err := os.Create("./xxx.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer file.Close()
    for i := 0; i < 5; i++ {
        file.WriteString("ab\n")
        file.Write([]byte("cd\n"))
    }
}

5. 读文件

文件读取可以用file.Read()和file.ReadAt(),读到文件末尾会返回io.EOF的错误

package main
import (
    "fmt"
    "io"
    "os"
)
func main() {
    // 打开文件
    file, err := os.Open("./xxx.txt")
    if err != nil {
        fmt.Println("open file err :", err)
        return
    }
    defer file.Close()
    // 定义接收文件读取的字节数组
    var buf [128]byte
    var content []byte
    for {
        n, err := file.Read(buf[:])
        if err == io.EOF {
            // 读取结束
            break
        }
        if err != nil {
            fmt.Println("read file err ", err)
            return
        }
        content = append(content, buf[:n]...)
    }
    fmt.Println(string(content))
}

6. 拷贝文件

package main
import (
    "fmt"
    "io"
    "os"
)
func main() {
    // 打开源文件
    srcFile, err := os.Open("./xxx.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    // 创建新文件
    dstFile, err2 := os.Create("./abc2.txt")
    if err2 != nil {
        fmt.Println(err2)
        return
    }
    // 缓冲读取
    buf := make([]byte, 1024)
    for {
        // 从源文件读数据
        n, err := srcFile.Read(buf)
        if err == io.EOF {
            fmt.Println("读取完毕")
            break
        }
        if err != nil {
            fmt.Println(err)
            break
        }
        //写出去
        dstFile.Write(buf[:n])
    }
    srcFile.Close()
    dstFile.Close()
}

7. bufio

  • bufio包实现了带缓冲区的读写,是对文件读写的封装
  • bufio缓冲写数据

os.O_WRONLY //只写 os.O_CREATE //创建文件 os.O_RDONLY //只读

os.O_RDWR //读写 os.O_TRUNC //清空 os.O_APPEND //追加

  • bufio读数据
package main
import (
    "bufio"
    "fmt"
    "io"
    "os"
)
func wr() {
    // 参数2:打开模式,所有模式d都在上面
    // 参数3是权限控制
    // w写 r读 x执行   w  2   r  4   x  1
    file, err := os.OpenFile("./xxx.txt", os.O_CREATE|os.O_WRONLY, 0666)
    if err != nil {
        return
    }
    defer file.Close()
    // 获取writer对象
    writer := bufio.NewWriter(file)
    for i := 0; i < 10; i++ {
        writer.WriteString("hello\n")
    }
    // 刷新缓冲区,强制写出
    writer.Flush()
}
func re() {
    file, err := os.Open("./xxx.txt")
    if err != nil {
        return
    }
    defer file.Close()
    reader := bufio.NewReader(file)
    for {
        line, _, err := reader.ReadLine()
        if err == io.EOF {
            break
        }
        if err != nil {
            return
        }
        fmt.Println(string(line))
    }
}
func main() {
    re()
}

以上就是Go语言IO输入输出底层原理及文件操作API的详细内容,更多关于Go IO操作输入输出API的资料请关注脚本之家其它相关文章!

相关文章

  • Go 分布式链路追踪实现原理解析

    Go 分布式链路追踪实现原理解析

    分布式链路追踪作为解决分布式应用可观测问题的重要技术,愈发成为分布式应用不可缺少的基础设施,本文将详细介绍分布式链路的核心概念、架构原理和相关开源标准协议,并分享我们在实现无侵入 Go 采集 Sdk 方面的一些实践,需要的朋友可以参考下
    2022-06-06
  • Golang配置解析神器go viper使用详解

    Golang配置解析神器go viper使用详解

    viper是一个很完善的Go项目配置解决方案,很多著名的开源项目都在使用,比如Hugo,Docker都使用了该库,使用viper可以让我们专注于自己的项目代码,而不用自己写那些配置解析代码,本文给大家介绍Golang配置解析神器go viper使用,感兴趣的朋友一起看看吧
    2022-05-05
  • go slice 扩容实现原理源码解析

    go slice 扩容实现原理源码解析

    这篇文章主要为大家介绍了go slice 扩容实现原理源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • 一文带你了解Go语言中的类型断言和类型转换

    一文带你了解Go语言中的类型断言和类型转换

    在Go中,类型断言和类型转换是一个令人困惑的事情,他们似乎都在做同样的事情。最明显的不同点是他们具有不同的语法(variable.(type) vs type(variable) )。本文我们就来深入研究一下二者的区别
    2022-09-09
  • 深入浅出Golang中select的实现原理

    深入浅出Golang中select的实现原理

    在go语言中,select语句就是用来监听和channel有关的IO操作,当IO操作发生时,触发相应的case操作,有了select语句,可以实现main主线程与goroutine线程之间的互动。本文就来详细讲讲select的实现原理,需要的可以参考一下
    2022-08-08
  • Go语言提升开发效率的语法糖技巧分享

    Go语言提升开发效率的语法糖技巧分享

    每门语言都有自己的语法糖,像java的语法糖就有方法变长参数、拆箱与装箱、枚举、for-each等等,Go语言也不例外。本文就来介绍一些Go语言的语法糖,需要的可以参考一下
    2022-07-07
  • golang 删除切片的某个元素及剔除切片内的零值方式

    golang 删除切片的某个元素及剔除切片内的零值方式

    这篇文章主要介绍了golang 删除切片的某个元素及剔除切片内的零值方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • 一文带你了解Go语言中函数设计的实践示例

    一文带你了解Go语言中函数设计的实践示例

    良好设计的函数具有清晰的职责和逻辑结构,提供准确的命名和适当的参数控制,下面我们将一一描述函数设计时能够遵循的最佳实践,希望对大家有所帮助
    2023-06-06
  • GoLang与Java各自生成grpc代码流程介绍

    GoLang与Java各自生成grpc代码流程介绍

    这篇文章主要介绍了GoLang与Java各自生成grpc代码流程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-03-03
  • 一文带你掌握掌握 Golang结构体与方法

    一文带你掌握掌握 Golang结构体与方法

    在 Golang 中,结构体和方法是实现面向对象编程的重要组成部分,也是 Golang 的核心概念之一。在本篇文章中,我们将深入介绍 Golang 结构体与方法的概念、使用方法以及相关的编程技巧和最佳实践
    2023-04-04

最新评论