Go中Writer和Reader接口的使用入门

目录
  • 引言
  • Writer 接口
  • Reader 接口
  • 总结

引言

我们学习其他语言编程时,会学到一个 io 包,这个包可以以流的方式高效处理数据,而不用考虑数据是什么,数据来自哪里,以及数据要发送到哪里的问题。

io 是一个 Golang 标准库包,它为围绕输入和输出的许多操作和用例定义了灵活的接口。

io 包参见:golang.org/pkg/io/

与 stdout 和 stdin 对应,Go 语言实现了 io.Writerio.Reader 两个接口。通过实现这两个接口,其他接口都可以使用 io 包提供的所有功能,也可以用于其他包里接收着两个接口的函数以及方法。

Go 还提供了名为 bufioioutil 的包,其中包含与使用这些接口相关的有用功能。

Writer 接口

io.Writer 接口是 Go 非常小的接口之一。它只有一种方法。写入方法。 Go 标准库中的许多包都使用 io.Writer 接口,它表示将字节切片写入数据流的能力。更一般地,允许您将数据写入实现 io.Writer 接口的东西。io.Writer 接口的声明如下:

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

这个接口声明了唯一一个方法 Writer,这个方法接收一个 byte 切片,并返回一个写入的字节数 n 和 error 错误值。

这里会有两个点需要注意:

  • Writer 从 p 字节切片的数据流写入 len(p) 字节的数据。这个方法返回从 p 里写出的字节数(0 <= n <= len(p) ),以及任何可能导致写入提起结束的错误。
  • Writer 在返回 n < len(p) 的时候,必须返回某个 nil 值的 error。Writer 绝不能改写切片里的数据,也不能临时修改。

现在来看一个例子,看在 Go 中将数据写入文件时如何使用 io.Writer

package main

import (
	"fmt"
	"os"
)

func main() {

	f, err := os.OpenFile("hello.txt", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	n, err := f.Write([]byte("Hello, My name is LeeLei!"))
	if err != nil {
		panic(err)
	}
	fmt.Printf("wrote %d bytes", n)
}

运行结果:wrote 25 bytes, 同时我们可以查看 hello.txt 文件内容:

os.File 的 Read 确实是同一个 io.Writer 接口的实现,用于将字节切片写入底层文件的数据流。这是 os.File.Write 的定义:

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

Reader 接口

然后来看一下 Reader 接口的声明:

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

Reader 是一个带有强抽象的小接口!那个抽象到底是什么? Read 方法的想法是它表示从某个源读取数据字节,以便我们可以在代码中使用这些字节。该来源可能是文件、相机、网络连接,或者只是一个普通的旧字符串。例如,如果我们从文件中读取数据,我们将使用的 io.Reader*os.File

io.Reader 接口声明了一个方法 Read,这个方法同样接受一个 byte 切片,返回两个值。第一个值是读入的字节数,第二个值是 error 错误值。

  • p []byte 是我们传递给 Read 方法的字节切片。 Reader 将从其数据源(如文件)读取的数据复制到该字节片。
  • 返回的 n int 告诉我们在这个 Read 调用中读取了多少字节。
  • 返回的 err error 是读取数据时可能发生的任何错误,例如到达文件末尾。

让我们用一个文件来尝试一下,看看我们是如何使用它的。复制此文本并将其保存到名为 hello.txt 的新目录中的文件中:

Hello, My name is LeeLei!

现在,让我们编写一些 Go 代码来使用 File 的 Read 方法读取它。复制此代码并将其保存到与 hello.txt 位于同一目录中的文件 main.go 中:

package main

import (
	"log"
	"os"
)

func main() {
	file, err := os.OpenFile("hello.txt", os.O_RDWR|os.O_CREATE|os.O_RDONLY, 0600)
	if err != nil {
		log.Fatalf("error opening hello.txt: %v", err)
	}
	defer file.Close()

	// Make a byte slice that's big enough to store a few words of the message
	// we're reading
	bytesRead := make([]byte, 33)

	// Now read some data, passing in our byte slice
	n, err := file.Read(bytesRead)
	if err != nil {
		log.Fatalf("error reading from hello.txt: %v", err)
	}

	// Take a look at the bytes we copied into the byte slice
	log.Printf("We read \"%s\" into bytesRead (%d bytes)",
		string(bytesRead), n)
}

运行该代码:go run main.go,然后可以看到如下输出:

$ go run main.go     
2022/04/18 22:56:29 We read "Hello, My name is LeeLei!" into bytesRead (25 bytes)

那么当我们调用 os.File.Read 时,Go 会从文件中读取数据,并将其复制到 bytesRead 中,由于没有发生错误,因此返回的错误为 nil。我们将 bytesRead 切片传递给 Read 函数,就像我们将杯子传递给汽水喷泉一样!

总结

本篇文章简单介绍了 Go 语言 io 包中的两个很实用的接口:Writer 和 Reader,分别给出了这两个接口的声明和解释,然后以一个简单的例子在代码中使用这两个小巧的接口,但是 Go 语言设计这两个接口的用法远远不止这些,也需要我们不断去探索其他功能,甚至学有余力去理解 Go 这样的设计的原理。

到此这篇关于Go中Writer和Reader接口的使用入门的文章就介绍到这了,更多相关Go Writer和Reader接口内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • GO语io包的常用接口

    本文实例分析了GO语io包的常用接口.分享给大家供大家参考.具体分析如下: 我没有 C/C++ 基础,没有接口的概念,且从 Python 投奔而来,Python 的极简主义(一个结果往往只提供一个方法),让我在 Golang 中非常迷糊,特别是文件的读写操作,因为 Go 的文件读写操作有很多的方法,让我不知道怎么选择.直到我学习了 interface 的概念,然后由看了 package io 后才慢慢理解,也渐渐的喜欢上了 Golang 的灵活性.以我的经验来说,接口是一个很重要的知识点,是一系

  • Golang极简入门教程(二):方法和接口

    方法 在 Golang 中没有类,不过我们可以为结构体定义方法.我们看一个例子: 复制代码 代码如下: package main   import (     "fmt"     "math" )   type Vertex struct {     X, Y float64 }   // 结构体 Vertex 的方法 // 这里的方法接收者(method receiver)v 的类型为 *Vertex func (v *Vertex) Abs() float64

  • Go语言中接口组合的实现方法

    本文实例讲述了Go语言中接口组合的实现方法.分享给大家供大家参考.具体实现方法如下: 在Go语言中,可以在接口A中组合其它的一个或多个接口(如接口B.C),这种方式等价于在接口A中添加接口B.C中声明的方法. 复制代码 代码如下: //接口中可以组合其它接口,这种方式等效于在接口中添加其它接口的方法  type Reader interface {      read()  }  type Writer interface {      write()  }    //定义上述两个接口的实现类 

  • Go语言接口用法实例

    本文实例讲述了Go语言接口用法.分享给大家供大家参考.具体分析如下: 接口类型是由一组方法定义的集合. 接口类型的值可以存放实现这些方法的任何值. 复制代码 代码如下: package main import (     "fmt"     "math" ) type Abser interface {     Abs() float64 } func main() {     var a Abser     f := MyFloat(-math.Sqrt2)   

  • golang中interface接口的深度解析

    一 接口介绍 如果说gorountine和channel是支撑起Go语言的并发模型的基石,让Go语言在如今集群化与多核化的时代成为一道亮丽的风景,那么接口是Go语言整个类型系列的基石,让Go语言在基础编程哲学的探索上达到前所未有的高度.Go语言在编程哲学上是变革派,而不是改良派.这不是因为Go语言有gorountine和channel,而更重要的是因为Go语言的类型系统,更是因为Go语言的接口.Go语言的编程哲学因为有接口而趋于完美.C++,Java 使用"侵入式"接口,主要表现在实现

  • Go语言中的方法、接口和嵌入类型详解

    概述 在 Go 语言中,如果一个结构体和一个嵌入字段同时实现了相同的接口会发生什么呢?我们猜一下,可能有两个问题: 1.编译器会因为我们同时有两个接口实现而报错吗? 2.如果编译器接受这样的定义,那么当接口调用时编译器要怎么确定该使用哪个实现? 在写了一些测试代码并认真深入的读了一下标准之后,我发现了一些有意思的东西,而且觉得很有必要分享出来,那么让我们先从 Go 语言中的方法开始说起. 方法 Go 语言中同时有函数和方法.一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的

  • Go语言使用swagger生成接口文档的方法

    swagger介绍 Swagger本质上是一种用于描述使用JSON表示的RESTful API的接口描述语言.Swagger与一组开源软件工具一起使用,以设计.构建.记录和使用RESTful Web服务.Swagger包括自动文档,代码生成和测试用例生成. 在前后端分离的项目开发过程中,如果后端同学能够提供一份清晰明了的接口文档,那么就能极大地提高大家的沟通效率和开发效率.可是编写接口文档历来都是令人头痛的,而且后续接口文档的维护也十分耗费精力. 最好是有一种方案能够既满足我们输出文档的需要又能

  • Go语言服务器开发实现最简单HTTP的GET与POST接口

    本文实例讲述了Go语言服务器开发实现最简单HTTP的GET与POST接口.分享给大家供大家参考.具体分析如下: Go语言提供了http包,可以很轻松的开发http接口.以下为示例代码: 复制代码 代码如下: package webserver    import (      "encoding/json"      "fmt"      "net/http"      "time"  )    func WebServerB

  • Go中Writer和Reader接口的使用入门

    目录 引言 Writer 接口 Reader 接口 总结 引言 我们学习其他语言编程时,会学到一个 io 包,这个包可以以流的方式高效处理数据,而不用考虑数据是什么,数据来自哪里,以及数据要发送到哪里的问题. io 是一个 Golang 标准库包,它为围绕输入和输出的许多操作和用例定义了灵活的接口. io 包参见:golang.org/pkg/io/ 与 stdout 和 stdin 对应,Go 语言实现了 io.Writer 和 io.Reader 两个接口.通过实现这两个接口,其他接口都可以

  • Java详细讲解IO流的Writer与Reader操作

    目录 接口连接 一.Writer方法 二.Reader方法 接口连接 public static void main(String[] args) throws Exception io流的所有方法都需要链接他们的接口父类,Exception. 一.Writer方法 方法引入: Writer Writer = new FileWriter("D:\\java制作\\高级特性\\src\\com\\ytzl\\第二章\\demo4\\io流\\two\\FileWriter方法.txt"

  • Java中反射动态代理接口的详解及实例

    Java语言中反射动态代理接口的解释与演示 Java在JDK1.3的时候引入了动态代理机制.可以运用在框架编程与平台编程时候捕获事件.审核数据.日志等功能实现,首先看一下设计模式的UML图解: 当你调用一个接口API时候,实际实现类继承该接口,调用时候经过proxy实现. 在Java中动态代理实现的两个关键接口类与class类分别如下: java.lang.reflect.Proxy java.lang.reflect.InvocationHandler 我们下面就通过InvocationHan

  • 详解Swift中对C语言接口缓存的使用以及数组与字符串转为指针类型的方法

    详解Swift中对C语言接口缓存的使用以及数组与字符串转为指针类型的方法 由于Swift编程语言属于上层编程语言,而Swift中由于为了低层的高性能计算接口,所以往往需要C语言中的指针类型,由此,在Swift编程语言刚诞生的时候就有了UnsafePointer与UnsafeMutablePointer类型,分别对应为const Type*类型与Type *类型. 而在Swift编程语言中,由于一般数组(Array)对象都无法直接用于C语言中含有指针类型的函数参数(比如:void*),所以往往需要

  • 基于C# 中可以new一个接口?的问题分析

    如果有人问你,C# 中可以new 一个接口吗?,你会怎么回答? 假设ITestInterface 是一个接口,那么这样的代码是否有问题? ITestInterface testInterface = new ITestInterface(); 很多书上都会说,当然有问题,接口不能用new ,然后你就认为上面这句语句肯定通不过编译器的编译了. 可是凡事无绝对,C# 竟然允许你这么写,当然你需要加点"料"才行. 在VS2005 中新建控制台程序CA2005.添加 Microsoft.Off

  • 详解Java中Comparable和Comparator接口的区别

    详解Java中Comparable和Comparator接口的区别 本文要来详细分析一下Java中Comparable和Comparator接口的区别,两者都有比较的功能,那么究竟有什么区别呢,感兴趣的Java开发者继续看下去吧. Comparable 简介 Comparable 是排序接口. 若一个类实现了Comparable接口,就意味着"该类支持排序".  即然实现Comparable接口的类支持排序,假设现在存在"实现Comparable接口的类的对象的List列表(

  • Java中如何动态创建接口的实现方法

    有很多应用场景,用到了接口动态实现,下面举几个典型的应用: 1.mybatis / jpa 等orm框架,可以在接口上加注解进行开发,不需要编写实现类,运行时动态产生实现. 2.dubbo等分布式服务框架,消费者只需要引入接口就可以调用远程的实现,分析源代码,其实在消费端产生了接口的代理实现,再由代理调用远程接口. 3.spring aop 这是最典型的动态代理了. 创建接口的动态实现,有二种最常用的方式:JDK动态代理和CGLIB动态代理. 代理模式是一种常用的设计模式,其目的就是为其他对象提

  • PHP中利用Telegram的接口实现免费的消息通知功能

    利用Telegram的接口,可以实现很方便的消息提醒,不用打开APP,不用科学联网,Telegram的通知就像短信提醒一样. 重点是,免费,无使用数量限制,不用担心短信内容审 查,你想发什么就发什么. 下面是利用php实现的发通知的代码: <?php $bot_api_key = 'CHANGE HERE'; function send_get($urlstring){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $urlstring); c

  • Kotlin中的sam(函数式接口)详解

    用lambda表达式去表示java中的匿名类实例 在使用java去给一个按钮设置监听我们通常会通过创建匿名类实例,如下 Button.setOnClickListener(new OnClickListener()){ @Override public void onClick(View v){ Toast.makeText(this,"Hello World",Toast.LENGTH_LONG).show() } } 在kotlin我们可以通过传递一个lambda表达式去代替这个实

  • 解决vue中使用Axios调用接口时出现的ie数据处理问题

    1.问题 近期在使用vue2 + axios 调用接口时碰到一个IE中很奇葩的问题,让我头痛了很久. 废话不多扯,就是在其他浏览器中调用接口返回数据然后可以很顺利的进行处理,但在IE(9-11)中发现发送请求是成功的而且也能抓到服务端返回来的数据.却发现在处理返回来的数据的时候处理的有点问题,怎么搞就是不行. 2.处理过程及方法 我使用了console大法去解决这个问题,具体是这样的:我先将服务器返回过来的数据打印到浏览器控制台,结果发现都能打印出来,这个时候就郁闷了,明明有数据为何在IE上还是

随机推荐