go语言中io操作中的 io.Reader 和 io.Writer的获取方法 总结

我们在对文件进行io操作的时候,经常看到需要我们传递一个 io.Reader 或者 io.Writer 对象作为读写的入参, 那么我们该如何或者这些个RW对象呢?  其实很简单,你只需要查找一下哪些对象实现了 Read或者 Writer方法,那么你只需要创建一个实现了这2个方法之一的对象 , 那他就可以是一个  io.Reader 或者 io.Writer 。

当然最常见的应该就是我们的 os.File对象了, 另外还有 bufio.Reader,  bytes.Buffer 等对象都可以作为io的RW入参。

 当然你也可以自己定义一个对象,实现  io.Reader 或者 io.Writer 接口中定义的方法,那么你的对象也可以作为一个RW入参来使用了。  这个也就是go语言中面向接口编程的完美体现。

go中Reader Writer接口定义

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

os.File对象中的RW实现代码


// Read reads up to len(b) bytes from the File and stores them in b.
// It returns the number of bytes read and any error encountered.
// At end of file, Read returns 0, io.EOF.
func (f *File) Read(b []byte) (n int, err error) {if err := f.checkValid("read"); err != nil {return 0, err}n, e := f.read(b)return n, f.wrapErr("read", e)
}// Write writes len(b) bytes from b to the File.
// It returns the number of bytes written and an error, if any.
// Write returns a non-nil error when n != len(b).
func (f *File) Write(b []byte) (n int, err error) {if err := f.checkValid("write"); err != nil {return 0, err}n, e := f.write(b)if n < 0 {n = 0}if n != len(b) {err = io.ErrShortWrite}epipecheck(f, e)if e != nil {err = f.wrapErr("write", e)}return n, err
}

bufio.Reader中的RW实现代码

// Read reads data into p.
// It returns the number of bytes read into p.
// The bytes are taken from at most one Read on the underlying Reader,
// hence n may be less than len(p).
// To read exactly len(p) bytes, use io.ReadFull(b, p).
// If the underlying Reader can return a non-zero count with io.EOF,
// then this Read method can do so as well; see the [io.Reader] docs.
func (b *Reader) Read(p []byte) (n int, err error) {n = len(p)if n == 0 {if b.Buffered() > 0 {return 0, nil}return 0, b.readErr()}if b.r == b.w {if b.err != nil {return 0, b.readErr()}if len(p) >= len(b.buf) {// Large read, empty buffer.// Read directly into p to avoid copy.n, b.err = b.rd.Read(p)if n < 0 {panic(errNegativeRead)}if n > 0 {b.lastByte = int(p[n-1])b.lastRuneSize = -1}return n, b.readErr()}// One read.// Do not use b.fill, which will loop.b.r = 0b.w = 0n, b.err = b.rd.Read(b.buf)if n < 0 {panic(errNegativeRead)}if n == 0 {return 0, b.readErr()}b.w += n}// copy as much as we can// Note: if the slice panics here, it is probably because// the underlying reader returned a bad count. See issue 49795.n = copy(p, b.buf[b.r:b.w])b.r += nb.lastByte = int(b.buf[b.r-1])b.lastRuneSize = -1return n, nil
}// writeBuf writes the Reader's buffer to the writer.
func (b *Reader) writeBuf(w io.Writer) (int64, error) {n, err := w.Write(b.buf[b.r:b.w])if n < 0 {panic(errNegativeWrite)}b.r += nreturn int64(n), err
}

bytes.Buffer中的RW实现代码


// Read reads the next len(p) bytes from the buffer or until the buffer
// is drained. The return value n is the number of bytes read. If the
// buffer has no data to return, err is io.EOF (unless len(p) is zero);
// otherwise it is nil.
func (b *Buffer) Read(p []byte) (n int, err error) {b.lastRead = opInvalidif b.empty() {// Buffer is empty, reset to recover space.b.Reset()if len(p) == 0 {return 0, nil}return 0, io.EOF}n = copy(p, b.buf[b.off:])b.off += nif n > 0 {b.lastRead = opRead}return n, nil
}// Write appends the contents of p to the buffer, growing the buffer as
// needed. The return value n is the length of p; err is always nil. If the
// buffer becomes too large, Write will panic with ErrTooLarge.
func (b *Buffer) Write(p []byte) (n int, err error) {b.lastRead = opInvalidm, ok := b.tryGrowByReslice(len(p))if !ok {m = b.grow(len(p))}return copy(b.buf[m:], p), nil
}

注意这些方法一般是绑定在指针类型的对象上, 所以你在创建你需要的RW对象的时候需要使用&指针符号或者使用 new函数来创建对象, 如:w := &bytes.Buffer{}  等效于  w := new(bytes.Buffer)

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

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

相关文章

ajax的请求解密

$.ajax({url: i,dataType: "json",success: function(e) {r.decompressAndDeobfuscateData(e, w).then((e>{if (!(e JSON.parse(e))[0].series[0].serie.data[0])return t(!0);e r.transformData(e),I && console.log("result:", e);解释每一…

uniapp 百度地图 拖动获取经纬度级搜索连用

import loadBMap from /utils/loadBMap.js// 百度聚合具体代码 // 拖动 initMapc() {let that thisloadBMap(百度key).then(() > {map new BMap.Map(mapContainer)const centerPoint new BMap.Point(this.longitude, this.latitude)map.centerAndZoom(centerPoint, this.…

Agilent MSO9404A、Keysight MSO9404A示波器,4 GHz,4 通道,20 GSa/s

Agilent MSO9404A、Keysight MSO9404A、HP MSO9404A 示波器&#xff0c;4 GHz&#xff0c;4 通道&#xff0c;20 GSa/s Keysight MSO9404A 示波器配备 15 英寸 XGA 显示屏&#xff0c;封装深度仅为 9 英寸&#xff08;23 厘米&#xff09;&#xff0c;重量仅为 26 磅&#xff…

AI地名故事:笔岗村

笔岗村&#xff0c;实际上是由笔村和宏岗村两个古老的村落合并而成的。南宋度宗元年&#xff0c;也就是公元1265年&#xff0c;笔村开始建立。随着时间的推移&#xff0c;到了宋代后期&#xff0c;宏岗村也相继建立。这两个村落各自承载着丰富的历史和文化&#xff0c;最终在历…

铁山靠之数学建模 - Matlab入门

Matlab基础 1. Matlab界面与基本操作1.1 matlab帮助系统1.2 matlab命令1.3 matlab功能符号1.4 matlab的数据类型1.5 函数计算1.6 matlab向量1.7 matlab多项式1.8 M文件1.9 函数文件1.10 matlab的程序结构1.11 echo、warning和error函数1.12 交互输入1.13 程序调试1.14 设置断点…

各个行业里做得比较好的SAAS平台(强烈建议收藏)

各个行业里做得比较好的SAAS平台&#xff0c;供大家参考&#xff01; 具体如下&#xff1a; 1、企业IM&#xff1a;钉钉、企业微信、班聊 2、IT运维平台&#xff1a;宝企通IT服务、卓豪 3、OA协同&#xff1a;织信、今目标、明道 4、人力资源&#xff1a;金柚网、51社保、…

‌‍‬⁣⁡​⁤⁢​⁢⁡⁣‬‍‌​​‬ ​‍⁤‬ ‬⁡⁡⁡‍‌‬⁡⁡⁢‬⁤⁢⁢⁤​‍‌​​‬ ​⁣‌绘唐3一键追爆款反推软件哪家好

‌‍‬⁣⁡​⁤⁢​⁢⁡⁣‬‍‌​​‬ ​‍⁤‬ ‬⁡⁡⁡‍‌‬⁡⁡⁢‬⁤⁢⁢⁤​‍‌​​‬ ​⁣‌绘唐3一键追爆款反推软件哪家好 支持单镜精绘&#xff0c;可以根据故事情节进行单镜头绘图调整&#xff0c;并支持对SD各类模型的自定义调整。 支持一键完成图文视频合成&am…

Windows11“重置此电脑”后,Edge浏览器在微软应用商店显示“已安装”,但是开始菜单搜索不到的解决办法

Windows11“重置此电脑”后&#xff0c;Edge浏览器在微软应用商店显示“已安装”&#xff0c;但是开始菜单搜索不到的解决办法 为什么重新使用Edge&#xff1f;问题描述不该更新可用更新问过AI&#xff08;通义千问&#xff09;&#xff0c;并且AI提供方法全都无效。现象 操作步…

国产分布式数据库高可用故障检测实现

在分布式数据库架构下&#xff0c;当数据库节点异常时&#xff0c;数据库管理组件能够自动感知到异常并触发节点隔离或者自动切换&#xff0c;是数据库高可用容灾的基本能力。在节点服务器异常、网络异常或进程异常等场景下&#xff0c;各数据库产品本身已经具备了可靠的检测能…

流动性生态协议MTMT正式登陆MEXC,将在5月13日开启交易

据悉&#xff0c;MTMT SFT流动性应用协议代币MTMT&#xff0c;在社区正式宣布即将登陆全球知名的加密货币交易平台MEXC&#xff0c;并将于5月13日正式上线并开放交易。 MTMT SFT流动性应用协议&#xff0c;全称Meta-Transaction Management Tool&#xff0c;是一个基于去中心化…

为什么说气膜是环保建筑呢—轻空间

气膜建筑&#xff0c;作为一种绿色环保建筑&#xff0c;其环保特性主要体现在以下几个方面&#xff1a; 1. 节约水资源&#xff1a; 气膜建筑在施工和运行过程中不需要大量水资源&#xff0c;与传统建筑相比&#xff0c;可以每年节约数万吨水资源。这种节约不仅有利于缓解水资源…

使用centos7搭建流媒体平台

实现流媒体直播 流媒体服务器&#xff0c;推流客户端&#xff0c;拉流客户端 硬件设施 centos7服务器&#xff0c;window拉流客户端 软件层面 dockersnginxrtmp模块 其他工具 git vlc 搭建rtmp服务器 这里是搭建服务器的环境 首先配置centos的环境 下载vmware vmware的…

【学习AI-相关路程-工具使用-自我学习-Ubuntucudavisco-开发工具尝试-基础样例 (2)】

【学习AI-相关路程-工具使用-自我学习-cuda&visco-开发工具尝试-基础样例 &#xff08;2&#xff09;】 1、前言2、环境说明3、总结说明4、工具安装0、验证cuda1、软件下载2、插件安装 5、软件设置与编程练习1、创建目录2、编译软件进入目录&创建两个文件3、编写配置文…

【iOS开发】—— 初识锁

【iOS开发】—— 初识锁 线程安全锁的种类自旋锁定义原理自旋锁缺点OSSpinLock&#xff08;自旋锁&#xff09; 互斥锁os_unfair_lockpthread_mutexNSLockNSRecusiveLockSemaphore信号量synchronized 总结两种之间的区别和联系&#xff1a; 线程安全 当一个线程访问数据的时候…

音视频开发4-补充 FFmpeg 开发环境搭建 -- ubuntu ffmpeg开发环境搭建

ubuntu ffmpeg开发环境搭建 1 创建目录 在 /home/hunandede/ffmpeg/ 目录下创建 ffmpeg_sources&#xff1a;用于下载源文件 ffmpeg_build&#xff1a; 存储编译后的库文件 bin&#xff1a;存储二进制文件&#xff08;ffmpeg&#xff0c;ffplay&#xff0c;ffprobe&#…

Request请求数据 (** kwargs参数)

目录 &#x1f31f;前言&#x1f349;request入门1. params2. data3. json4. headers5. cookies6. auth7. files8. timeout9. proxies10. allow_redirects11. stream12. verify13. cert &#x1f31f;总结 &#x1f31f;前言 在Python中&#xff0c;发送网络请求是一项常见的任…

Linux----磁盘操作

1.在Linux中要使用一个新的磁盘&#xff0c;通常可以按照哪几个步骤进行&#xff1f; 在Linux中要使用一个新的磁盘&#xff0c;通常可以按照以下步骤进行&#xff1a; 查看磁盘&#xff1a;使用 fdisk -l 等命令查看新磁盘是否被系统识别。分区&#xff1a;使用 fdisk 或 gdis…

淘宝商品评论电商API接口,让你购物不再困扰

现在的时代购物已经成为了人们生活中不可或缺的一部分。然而&#xff0c;面对琳琅满目的商品&#xff0c;我们常常犯愁&#xff0c;不知道如何选择。为了解决这个问题&#xff0c;淘宝推出了商品评论电商API接口&#xff0c;为广大消费者提供了极大的便利。联讯数据将详细介绍淘…

数据挖掘实战-基于决策树算法构建银行贷款审批预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

6818Linux内核--Bootloader应用分析

Bootloader应用分析 一个嵌入式 Linux 系统从软件的角度看通常可以分为四个层次&#xff1a; 引导加载程序。包括固化在固件( firmware )中的 boot 代码(可选)&#xff0c;和 Boot Loader 两大部分。 Linux 内核。特定于嵌入式板子的定制内核以及内核的启动参数。 文件系统…