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

2024-05-12 16:52

本文主要是介绍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)

这篇关于go语言中io操作中的 io.Reader 和 io.Writer的获取方法 总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/983192

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

浅谈主机加固,六种有效的主机加固方法

在数字化时代,数据的价值不言而喻,但随之而来的安全威胁也日益严峻。从勒索病毒到内部泄露,企业的数据安全面临着前所未有的挑战。为了应对这些挑战,一种全新的主机加固解决方案应运而生。 MCK主机加固解决方案,采用先进的安全容器中间件技术,构建起一套内核级的纵深立体防护体系。这一体系突破了传统安全防护的局限,即使在管理员权限被恶意利用的情况下,也能确保服务器的安全稳定运行。 普适主机加固措施:

webm怎么转换成mp4?这几种方法超多人在用!

webm怎么转换成mp4?WebM作为一种新兴的视频编码格式,近年来逐渐进入大众视野,其背后承载着诸多优势,但同时也伴随着不容忽视的局限性,首要挑战在于其兼容性边界,尽管WebM已广泛适应于众多网站与软件平台,但在特定应用环境或老旧设备上,其兼容难题依旧凸显,为用户体验带来不便,再者,WebM格式的非普适性也体现在编辑流程上,由于它并非行业内的通用标准,编辑过程中可能会遭遇格式不兼容的障碍,导致操

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti

二分最大匹配总结

HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter