一文掌握 Go 语言 I/O 操作中的 io.Reader 和 io.Writer

文章精选推荐

1 JetBrains Ai assistant 编程工具让你的工作效率翻倍
2 Extra Icons:JetBrains IDE的图标增强神器
3 IDEA插件推荐-SequenceDiagram,自动生成时序图
4 BashSupport Pro 这个ides插件主要是用来干嘛的 ?
5 IDEA必装的插件:Spring Boot Helper的使用与功能特点
6 Ai assistant ,又是一个写代码神器

文章正文

在 Go 语言中,io.Readerio.Writer 是两个非常重要的接口,它们在许多标准库中都扮演着关键角色,尤其是在 I/O 操作中。理解它们的作用和用法,是掌握 Go 语言 I/O 操作的基础。

1. io.Readerio.Writer 接口

Go 语言通过接口的方式提供了灵活的 I/O 操作,io.Readerio.Writer 就是这两个核心接口,它们用于定义基本的输入输出操作。

io.Reader 接口

io.Reader 接口用于从数据源(如文件、网络连接、内存等)读取数据。其定义非常简单:

package iotype Reader interface {Read(p []byte) (n int, err error)
}
  • Read(p []byte)Read 方法从数据源读取最多 len(p) 字节的数据,并将其存储在 p 中,返回实际读取的字节数 n 和可能发生的错误 err。返回的 err 可以是 nil(表示成功),也可以是其他错误,比如 EOF(文件结尾)错误,表示数据已经读取完毕。

io.Reader 的常见实现包括 os.Filebytes.Buffernet.Conn 等。

io.Writer 接口

io.Writer 接口用于将数据写入到某个数据目标(如文件、网络连接、内存等)。其定义如下:

package iotype Writer interface {Write(p []byte) (n int, err error)
}
  • Write(p []byte)Write 方法将 p 中的数据写入到目标数据源,并返回实际写入的字节数 n 和可能发生的错误 err

io.Writer 的常见实现包括 os.Filebytes.Buffernet.Conn 等。

2. io.Readerio.Writer 的使用示例

示例 1:io.Reader 的使用

我们来看一个简单的例子,使用 io.Reader 从文件中读取数据并打印到标准输出。

package mainimport ("fmt""io""os"
)func main() {// 打开一个文件file, err := os.Open("example.txt")if err != nil {fmt.Println("Error opening file:", err)return}defer file.Close()// 创建一个缓冲区buf := make([]byte, 8) // 每次读取 8 字节// 从文件中读取数据for {n, err := file.Read(buf)if err == io.EOF {break // 读取完毕}if err != nil {fmt.Println("Error reading file:", err)return}// 打印读取的内容fmt.Print(string(buf[:n]))}
}

在这个例子中:

  • file 实现了 io.Reader 接口。
  • 我们使用 file.Read(buf) 从文件中读取数据并存入 buf
  • 每次读取最多 8 字节,直到遇到 EOF(文件结束)。
示例 2:io.Writer 的使用

接下来我们看一个简单的例子,使用 io.Writer 将数据写入到文件中。

package mainimport ("fmt""io""os"
)func main() {// 创建一个文件file, err := os.Create("output.txt")if err != nil {fmt.Println("Error creating file:", err)return}defer file.Close()// 要写入的内容data := "Hello, Go I/O!\n"// 将数据写入文件n, err := file.Write([]byte(data))if err != nil {fmt.Println("Error writing to file:", err)return}fmt.Printf("Wrote %d bytes to file\n", n)
}

在这个例子中:

  • file 实现了 io.Writer 接口。
  • 我们通过 file.Write([]byte(data)) 将数据写入到文件中。
示例 3:组合使用 io.Readerio.Writer

Go 中的 I/O 操作经常涉及到从一个 Reader 读取数据,然后将数据写入到一个 Writer。例如,将一个文件的内容复制到另一个文件:

package mainimport ("fmt""io""os"
)func main() {// 打开源文件src, err := os.Open("example.txt")if err != nil {fmt.Println("Error opening source file:", err)return}defer src.Close()// 创建目标文件dst, err := os.Create("copy.txt")if err != nil {fmt.Println("Error creating destination file:", err)return}defer dst.Close()// 将文件内容从 src 复制到 dstn, err := io.Copy(dst, src)if err != nil {fmt.Println("Error copying file:", err)return}fmt.Printf("Successfully copied %d bytes\n", n)
}

在这个例子中:

  • src 实现了 io.Reader 接口(我们从文件中读取数据)。
  • dst 实现了 io.Writer 接口(我们将数据写入到文件)。

io.Copy 函数将 src 中的数据读取并写入到 dst,直到读取完毕。

3. io.Readerio.Writer 的一些重要实现

bytes.Buffer

bytes.Bufferio.Readerio.Writer 的常见实现,它在内存中作为缓冲区来读取和写入数据。可以用于处理字符串或二进制数据。

package mainimport ("bytes""fmt"
)func main() {// 创建一个新的 Buffervar buf bytes.Buffer// 使用 Writer 接口写入数据buf.Write([]byte("Hello, Go!"))// 使用 Reader 接口读取数据data := buf.String()fmt.Println(data) // 输出:Hello, Go!
}
os.File

os.File 类型也实现了 io.Readerio.Writer 接口。通过它可以直接进行文件的读取和写入。

package mainimport ("fmt""os"
)func main() {// 打开一个文件(只读模式)file, err := os.Open("example.txt")if err != nil {fmt.Println("Error opening file:", err)return}defer file.Close()// 读取文件内容buf := make([]byte, 1024)n, err := file.Read(buf)if err != nil {fmt.Println("Error reading file:", err)return}fmt.Printf("Read %d bytes: %s\n", n, buf[:n])
}

4. io.Readerio.Writer 的高级应用

1. io.TeeReader

io.TeeReader 是一个非常有用的函数,它可以将一个 Reader 的输出同时传递给另一个 Writer,相当于将数据复制一份。可以用于日志记录或调试。

package mainimport ("fmt""io""os"
)func main() {// 创建一个文件file, err := os.Create("output.txt")if err != nil {fmt.Println("Error creating file:", err)return}defer file.Close()// 创建一个 TeeReader,读取来自 stdin,同时写入到文件tee := io.TeeReader(os.Stdin, file)// 从 tee 中读取输入buf := make([]byte, 1024)n, err := tee.Read(buf)if err != nil && err != io.EOF {fmt.Println("Error reading input:", err)return}// 输出读取的数据fmt.Printf("Read %d bytes: %s\n", n, buf[:n])
}

在这个例子中,TeeReader 会将 stdin 的输入同时写入到 output.txt 文件中。

2. io.Pipe

io.Pipe 用于创建一个管道,它的 ReaderWriter 可以在不同的 goroutine 中进行并发操作,适用于管道流式处理。

package mainimport ("fmt""io"
)func main() {// 创建一个管道pr, pw := io.Pipe()// 在一个 goroutine 中写数据go func() {defer pw.Close()pw.Write([]byte("Hello, Pipe!"))}()// 读取数据buf := make([]byte, 1024)n, _ := pr.Read(buf)fmt.Printf("Read from pipe: %s\n", string(buf[:n]))
}

总结

  • io.Reader:用于从数据源读取数据,Read 方法将数据读入给定的字节切片。
  • io.Writer:用于将数据写入目标,Write 方法将数据写入指定的目标。
  • 通过 `

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/889249.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

敏捷开发04:Scrum 中的 Product Backlog(产品待办列表) 详细介绍

Product Backlog 产品待办列表 在计划开发产品功能时,都希望产品功能上线后,用户能够喜欢并经常使用。 因此在开发产品新功能时,就要衡量哪些产品需求是对用户最有价值,这是最应该思考的问题。 然后把这些有价值的需求集合放在一…

vmware vsphere5---部署vCSA(VMware vCenter Server)附带第二阶段安装报错解决方案

声明 因为这份文档我是边做边写的,遇到问题重新装了好几次所以IP会很乱 ESXI主机为192.168.20.10 VCSA为192.168.20.7,后台为192.168.20.7:5480 后期请自行对应,后面的192.168.20.57请对应192.168.20.7,或根据自己的来 第一阶段…

USB Ping 事务

文章目录 USB Ping 事务Ping 事务处理机制Ping 示例完整抓包USB Ping 事务 在低速和全速模式下,USB 主机使用控制传输或者批量传输向 USB 设备发送数据时,如果 USB 设备因某些原因(如内存空间不足)无法接收数据,USB 设备会向 USB 主机返回 NAK 包。如果 USB 设备一直无法接…

110.【C语言】编写命令行程序(1)

目录 1.前置知识 "命令"的含义 运行C语言程序 2.介绍 main函数的参数 实验1 执行结果 实验2 执行结果 修改代码 实验3 分析 方法:遍历数组argv[]中的所有参数 执行结果 修改代码 执行结果 1.前置知识 "命令"的含义 WINR输入cmd,在cmd窗口下…

android NumberPicker隐藏分割线或修改颜色

在 Android 中,可以通过以下几种方法隐藏 NumberPicker 的分割线: 使用 XML 属性设置 在布局文件中的 NumberPicker 标签内添加 android:selectionDividerHeight"0dp" 属性,将分割线的高度设置为 0,从而达到隐藏分割线…

Leecode刷题C语言之半有序排列

执行结果:通过 执行用时和内存消耗如下&#xff1a; 代码如下&#xff1a; int semiOrderedPermutation(int* nums, int numsSize) {int first 0, last 0;for (int i 0; i < numsSize; i) {if (nums[i] 1) {first i;}if (nums[i] numsSize) {last i;}}return firs…

RPC设计--从reactor设计 (IOthread)

主从reactor架构 一般的一个网络IO库都是主从reactor模式&#xff0c;即主线程中有一个MainReactor&#xff0c;其负责监听ListenFd&#xff0c;当接受到新的用户连接时&#xff0c;返回的clientfd并不会加入的MainReacotr&#xff0c;而是在子线程&#xff08;这里称为IO线程&…

Scala中求斐波那契数列的第n项

求斐波那契数列的第n项 问题&#xff1a;求 斐波那契数列的第n项 记&#xff1a; 0 1 1 2 3 5 8 13 21 34 55 ... 从第3项开始 f(n) f(n-1) f(n-2) 1.基本情况&#xff08;直接能求的&#xff09;&#xff1a;f(0) 0,f(1) 1 2.递归情况&#xff08;大事化小&#xff0c;自己…

【Anaconda/Miniconda conda 常用命令】

【Anaconda/Miniconda conda 常用命令】 1. 虚拟环境管理查看虚拟环境创建虚拟环境激活/退出虚拟环境删除虚拟环境 2. 包管理安装包更新包卸载包查看已安装的包 3. 环境导出与迁移导出环境导入环境 4. 清理与优化清理缓存 5. 常见信息查询查询环境/包 6. 其他实用命令切换频道更…

【Golang】Go语言编程思想(六):Channel,第六节,并发编程模式

并发模式 下例重新对 channel 的用法进行回顾&#xff1a; package mainimport ("fmt""math/rand""time" )func msgGen(name string) chan string {c : make(chan string)go func(name string) { // 在这个 goroutine 当中向外发送数据i : 0fo…

重生之我在异世界学编程之C语言:深入结构体篇(上)

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文《1》 结构体的两种声明一、结构…

Scala递归中求汉罗塔游戏的步骤

记&#xff1a;f(n,"A","B","C")表示n个盘子从A柱子上移动到C柱子上&#xff0c;借用B柱子的过程 f(要移动的盘子的个数&#xff0c;起点&#xff0c;辅助柱子&#xff0c;终点) 1.基本情况(直接能求的)&#xff1a;f(1,"A","B&…

[代码随想录Day34打卡] 62.不同路径 63. 不同路径 II 343. 整数拆分 (可跳过)96.不同的二叉搜索树 (可跳过)

62.不同路径 和上楼梯相同&#xff0c;机器人只可以向右向下移动。所以在位置[i,j]有两种情况&#xff0c;一种从[i-1, j]向右移动到达当前位置&#xff0c;或者从[i, j-1]向下移动到当前位置。所以到达当前位置的方法数量就等于到达[i, j-1]和到达[i-1, j]的方法数量的和。 简…

使用Jackson库的ObjectMapper类将Java的Set集合转换为JSON数组

本教程展示如何使用Jackson库的ObjectMapper类将Java的Set集合转换为JSON数组。 由于Set是一个不允许重复元素且不保证元素顺序的集合&#xff0c;所以当它被序列化为JSON数组时&#xff0c;其元素的顺序可能与插入时不同。下面是具体步骤和代码示例。 添加依赖项 首先&…

输入url到显示主页的详细过程

从浏览器地址输入url到显示主页的过程&#xff1f; 主要分为&#xff1a;DNS解析&#xff0c;TCP连接&#xff0c;发送HTTP请求&#xff0c;服务器处理请求&#xff0c;浏览器接收HTTP响应&#xff0c;断开连接 DNS解析&#xff1a; 浏览器发起一个DNS请求到DNS服务器&#…

使用C#通过ColorMatrix对象为图像重新着色

此示例产生了一些令人印象深刻的结果&#xff0c;但实际上非常简单。 它使用其他几个示例演示的 ImageAttribute 技术来快速操作图像的颜色。 下面的AdjustColor方法启动图像着色的过程。 // Adjust the images colors. private Image AdjustColor(Image image) {// Make the …

手机租赁系统开发全流程解析与实用指南

内容概要 在如今快速发展的科技时代&#xff0c;手机租赁系统已经成为一种新兴的商业模式&#xff0c;非常符合当下市场需求。那么&#xff0c;在开发这样一个系统的时候&#xff0c;首先要从需求分析和市场调研开始。在这一阶段&#xff0c;你需要了解用户需要什么&#xff0…

unity打包web,如何减小文件体积,特别是 Build.wasm.gz

unity打包WebGL&#xff0c;使用的是wasw&#xff0c;最终生成的Build.wasm.gz体积很大&#xff0c;有6.5M&#xff0c;有几个方法可以稍微减小这个文件的大小 1. 裁剪引擎代码&#xff1a; 此步可将大小从6.5减小到 6.2&#xff08;此项默认开启&#xff0c;只是改了裁剪等级…

字符集编码

由于计算机只能存储和处理二进制的“0”和“1”&#xff0c;无法处理其他的字母、数字和符号&#xff0c;所以就需要有某种东西来达到类似桥梁的作用——例如图1-7中的ASCII——通过它&#xff0c;人们就可以看懂用计算机表示字母、数字或其他符号。 人们能够想到的最直接的方…

OceanBase 社区版 4.0 离线方式升级bp1至bp2 指南(含避坑总结)

注&#xff1a;目前社区版对 4.0 升级 bp1至 bp2也未有完善的文档&#xff0c;本次升级中也是遇到不少坑&#xff0c;写本文也希望对OB感兴趣的可以尝试少些遇坑。 也希望对升级有更好方式建议方式的朋友一起切磋交流&#xff0c;以便再进一步完善升级方案。 第一次做OB的升级&…