• 标准库之input&output


    1、基本的io接口

      在 io 包中最重要的是两个接口:Reader 和 Writer 接口。

      1.1Reader接口

    Reader 接口的定义如下:

    type Reader interface {
        Read(p []byte) (n int, err error)
    }
    

    Read 将 len(p) 个字节读取到 p 中。它返回读取的字节数 n(0 <= n <= len(p)) 以及任何遇到的错误。即使 Read 返回的 n < len(p),它也会在调用过程中占用 len(p) 个字节作为暂存空间。若可读取的数据不到 len(p) 个字节,Read 会返回可用数据,而不是等待更多数据。

    当 Read 在成功读取 n > 0 个字节后遇到一个错误或 EOF (end-of-file),它会返回读取的字节数。它可能会同时在本次的调用中返回一个non-nil错误,或在下一次的调用中返回这个错误(且 n 为 0)。 一般情况下, Reader会返回一个非0字节数n, 若 n = len(p) 个字节从输入源的结尾处由 Read 返回,Read可能返回 err == EOF 或者 err == nil。并且之后的 Read() 都应该返回 (n:0, err:EOF)。

    调用者在考虑错误之前应当首先处理返回的数据。这样做可以正确地处理在读取一些字节后产生的 I/O 错误,同时允许EOF的出现。

    场景举例:

    func ReadFrom(reader io.Reader, num int) ([]byte, error) {
        p := make([]byte, num)
        n, err := reader.Read(p)
        if n > 0 {
            return p[:n], nil
        }
        return p, err
    }
    
    main(){
        // 从标准输入读取
        data, err = ReadFrom(os.Stdin, 11)
    
        // 从普通文件读取,其中 file 是 os.File 的实例
        data, err = ReadFrom(file, 9)
    
        // 从字符串读取
        data, err = ReadFrom(strings.NewReader("from string"), 12)
    }
    

    1.2Writer接口

    Writer 接口的定义如下:

    type Writer interface {
        Write(p []byte) (n int, err error)
    }
    

    Write 将 len(p) 个字节从 p 中写入到基本数据流中。它返回从 p 中被写入的字节数 n(0 <= n <= len(p))以及任何遇到的引起写入提前停止的错误。若 Write 返回的 n < len(p),它就必须返回一个 非nil 的错误。

    场景举例:

    //在使用 Go 语言进行 Web 开发时,http.ResponseWriter 是最基本的类型之一,它本身是一个 Interface 类,原型如下:
    type ResponseWriter interface { Header() Header Write([]byte) (int, error) WriteHeader(int) }
    //直接调用 Write() 写入一串 []byte func helloHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain") w.Write([]byte("Hello World")) return } func main() { http.HandleFunc("/", helloHandler) http.ListenAndServe(":8080", nil) }

    1.3实现了 io.Reader 接口或 io.Writer 接口的类型

    围绕io.Reader/Writer,有几个常用的实现:

    • net.Conn, os.Stdin, os.File: 网络、标准输入输出、文件的流读取
    • strings.Reader: 把字符串抽象成Reader
    • bytes.Reader: 把[]byte抽象成Reader
    • bytes.Buffer: 把[]byte抽象成Reader和Writer
    • bufio.Reader/Writer: 抽象成带缓冲的流读取(比如按行读写)

    2、ReaderAt 和 WriterAt 接口

    2.1ReaderAt 接口

    ReaderAt 接口的定义如下:
    type ReaderAt interface {
        ReadAt(p []byte, off int64) (n int, err error)
    }

    ReadAt 从基本输入源的偏移量 off 处开始,将 len(p) 个字节读取到 p 中。它返回读取的字节数 n(0 <= n <= len(p))以及任何遇到的错误。

    当 ReadAt 返回的 n < len(p) 时,它就会返回一个 非nil 的错误来解释 为什么没有返回更多的字节。在这一点上,ReadAt 比 Read 更严格。

    即使 ReadAt 返回的 n < len(p),它也会在调用过程中使用 p 的全部作为暂存空间。若可读取的数据不到 len(p) 字节,ReadAt 就会阻塞,直到所有数据都可用或一个错误发生。 在这一点上 ReadAt 不同于 Read。

    若 n = len(p) 个字节从输入源的结尾处由 ReadAt 返回,Read可能返回 err == EOF 或者 err == nil

    若 ReadAt 携带一个偏移量从输入源读取,ReadAt 应当既不影响偏移量也不被它所影响。

    可对相同的输入源并行执行 ReadAt 调用。

    场景举例:

    reader := strings.NewReader("Go语言中文网")
    p := make([]byte, 6)
    n, err := reader.ReadAt(p, 2)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%s, %d\n", p, n)

    2.2WriterAt 接口

    WriterAt 接口的定义如下:
    type WriterAt interface {
        WriteAt(p []byte, off int64) (n int, err error)
    }
    

    WriteAt 从 p 中将 len(p) 个字节写入到偏移量 off 处的基本数据流中。它返回从 p 中被写入的字节数 n(0 <= n <= len(p))以及任何遇到的引起写入提前停止的错误。若 WriteAt 返回的 n < len(p),它就必须返回一个 非nil 的错误。

    若 WriteAt 携带一个偏移量写入到目标中,WriteAt 应当既不影响偏移量也不被它所影响。

    若被写区域没有重叠,可对相同的目标并行执行 WriteAt 调用。

    场景举例:

    file, err := os.Create("writeAt.txt")
    if err != nil {
        panic(err)
    }
    defer file.Close()
    file.WriteString("Golang中文社区——这里是多余")
    n, err := file.WriteAt([]byte("Go语言中文网"), 24)
    if err != nil {
        panic(err)
    }
    fmt.Println(n)

    3、ReaderFrom 和 WriterTo 接口

    3.1ReaderFrom 接口

    ReaderFrom 的定义如下:

    type ReaderFrom interface {
        ReadFrom(r Reader) (n int64, err error)
    }
    

    ReadFrom 从 r 中读取数据,直到 EOF 或发生错误。其返回值 n 为读取的字节数。除 io.EOF 之外,在读取过程中遇到的任何错误也将被返回。

    如果 ReaderFrom 可用,Copy 函数就会使用它。

    ReadFrom 方法不会返回 err == EOF。

    场景举例:

    //将文件中的数据全部读取(显示在标准输出)
    file, err := os.Open("writeAt.txt")
    if err != nil {
        panic(err)
    }
    defer file.Close()
    writer := bufio.NewWriter(os.Stdout)
    writer.ReadFrom(file)
    writer.Flush()
     

    3.2WriterTo接口

    WriterTo的定义如下:
    type WriterTo interface {
        WriteTo(w Writer) (n int64, err error)
    }
    

    WriteTo 将数据写入 w 中,直到没有数据可写或发生错误。其返回值 n 为写入的字节数。 在写入过程中遇到的任何错误也将被返回。

    如果 WriterTo 可用,Copy 函数就会使用它。

    场景举例:

    //将一段文本输出到标准输出
    reader := bytes.NewReader([]byte("Go语言中文网"))
    reader.WriteTo(os.Stdout)

    4、Seeker 接口

    接口定义如下:

    type Seeker interface {
        Seek(offset int64, whence int) (ret int64, err error)
    }
    

      Seek 设置下一次 Read 或 Write 的偏移量为 offset,它的解释取决于 whence: 0 表示相对于文件的起始处,1 表示相对于当前的偏移,而 2 表示相对于其结尾处。 Seek 返回新的偏移量和一个错误,如果有的话。

    场景举例:

    //获取倒数第二个字符
    reader := strings.NewReader("Go语言中文网")
    reader.Seek(-6, io.SeekEnd)
    r, _, _ := reader.ReadRune()
    fmt.Printf("%c\n", r)
    

    5、Closer接口

    接口定义如下:
    type Closer interface {
        Close() error
    }
    

    该接口比较简单,只有一个 Close() 方法,用于关闭数据流。

    文件 (os.File)、归档(压缩包)、数据库连接、Socket 等需要手动关闭的资源都实现了 Closer 接口。

     
     
     
     
  • 相关阅读:
    三种实现AJAX的方法以及Vue和axios结合使用的坑
    一个简陋的个人小项目,也是个人第一个真正意义上的独立项目——Graph
    使用docsify并定制以使它更强大
    使用particles.js实现网页背景粒子特效
    使用nginx和tomcat配置反向代理和动静分离
    php (zip)文件下载设置
    php 获取当前完整url地址
    php 实现重定向的三种方式
    php 查看使用多少内存
    linux 查看系统信息
  • 原文地址:https://www.cnblogs.com/mango1997/p/16305720.html
Copyright © 2020-2023  润新知