go语言内置io包中TreeReader函数的理解和使用示例

      在go语言的内置io包中的这个 TreeReader函数,函数原型 func TeeReader(r Reader, w Writer) Reader   从函数原型中看是给他一个Reader, 和一个Writer 然后他给你返回一个Reader,  本文中我们把这个返回的Reader叫做 treeReader, 他是一个很特别的reader,。

        他的作用就是将你输入的 r 和w建立一个对应关系, 当你在读取这个treeReader的时候,他会将读取到的数据同时写入到w中。同时在他的内部没有缓存,写入必须在读取完成之前完成。写入时遇到的任何错误都会报告为读取错误。

     这个是官方的解释: “ TeeReader returns a Reader that writes to w what it reads from r. All reads from r performed through it are matched with corresponding writes to w. There is no internal buffering - the write must complete before the read completes. Any error encountered while writing is reported as a read error. ”   对于非英语母语的人来说看起来是不是有点绕啊? 😆

          知道了他的作用, 那我们就可以根据他的作用来给他找合适的用处了, 我们一般用它来统计文件下载进度, 还有计算文件的HASH值等。

       

先看看官方给的小示例

  这里的用途是在读取treeReader的时候同步将数据打印到标准输出中。

package mainimport ("io""log""os""strings"
)func main() {var r io.Reader = strings.NewReader("some io.Reader stream to be read\n")r = io.TeeReader(r, os.Stdout)// Everything read from r will be copied to stdout.if _, err := io.ReadAll(r); err != nil {log.Fatal(err)}}

使用io.ReeeReader来计算文件的hash值 sha256 Example测试用例


func ExampleCalSha() {file, err := os.Open("testdata/test.zip")if err != nil {fmt.Println("error opening file: ", err)return}hash256 := sha256.New()treeReader := io.TeeReader(file, hash256)// 又拷贝回去io.Copy(file, treeReader) // 这个的意义就在于用它来从treeReader中读取数据的同时写入到hash256中b256 := hash256.Sum(nil)fmt.Printf("文件 %v SHA256: %X", file.Name(), b256) // output: a
}

使用io.TreeReader来实时显示文件的下载进度

这个很简单,我们只需要自定义一个Writer, 然后 利用TreeReader将下载文件的返回流 resp.Body和我们自定义的这个Writer建议对应关系, 然后我们再来读取这treeReader的数据, 在我们呢读取数据的时候也会同步的将数据发送到我们自定义的Writer中, 我们的下载进度显示就在我们自定义的Writer中完成。  我们可以使用  io.Copy(outfile, treeReader) 来从treeReader中读取数据并拷贝到outfile输出文件中。

自定义的用来显示下载进度的Writer对象


// 自定义的用来统计和显示下载进度的对象
type DownProgress struct {CLen  uint64 //数据的总长度Total uint64 // 用来记录数据的总写入长度
}// 注意,这个方法只有在treeReader中的数据被读取之后才会被调用, 每读一次这里调用一次
func (w *DownProgress) Write(b []byte) (int, error) {n := len(b) // number of bytes writtenw.Total += uint64(n)// 打印下载进度// 获取当前下载进度百分比,需要将除数和被除数数据类型都转为float64percent := float64(w.Total) / float64(w.CLen) * 100// 打印当前下载进度 注意这里的 %.2f 表示格式化浮点数 2位小数, 后面的 %% 表示在显示一个百分号 %fmt.Printf("\r下载中...  已完成百分比 %.2f%% ", percent)// 打印下载进度 endreturn n, nil
}

自定义Writer的使用

    resp,err:=http.DefaultClient.Get("https://cn.bing.com/th?id=OHR.MPPUnesco_ZH-CN8076198158_UHD.jpg")if err != nil {fmt.Println("request error: ", err)return}defer resp.Body.Close()// 创建保存文件outfile, err := os.Create("abc.jpg")if err != nil {return err}defer outfile.Close()// 自定义一个用来统计下载进度的WriterdownProgress := &DownProgress{CLen: uint64(resp.ContentLength)} // 下载进度显示对象, 这里利用io.TeeReader 将下载对象的数据和这个自定义的Writerd读取进行绑定, 在treeReader读取数据后会同步写入到这个自定义的write中,用来统计下载进度.treeReader := io.TeeReader(resp.Body, downProgress) //将自定义的writer和resp.Body建立联系io.Copy(outfile, treeReader) // 读取数据

执行后即可见到你的下载进度从0%到 100%显示
下载中...  已完成百分比 100.00% 
 

还有其他的用法? 等待你的发现和探索。。。。。。

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

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

相关文章

利用STK分析雷达干扰

利用STK中的radar模块能够进行干扰分析。该模块能够用来确定干扰源(单站雷达、发射源),评估干扰对本机雷达性能的影响。 在分析干扰影响之前,首先设置一简单场景。 1、创建一个名为RadarJam的场景; 2、打开场景的Prop…

上位机图像处理和嵌入式模块部署(f103 mcu运行freertos)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 mcu一般有两个用途,一个是控制,一个是非控制。控制类的应用一般要求实时性比较高,什么时候做什么,都是有严格的时间要求的。而非控制类的应用,则要求实现尽可能多的功能,比如…

spring boot整合j2cache 配置项目全局键标识 帮助定位是哪个项目产生的缓存

我们利用 j2cache 存进 redis的缓存 key 可以加个全局标识 这样 到时看缓存 方便别人看是哪个项目存进去的 例如 这里 我们存入的 book 我们 keys * 查看 就知道是个book 但不知道具体来自那套系统 我们在 j2cache.properties 中加上 redis.namespace 项目全局键标识 我们…

技术分享:深入C++时间操作函数的应用与实践

在软件开发中,时间是无处不在的一个概念,无论是日志记录、定时任务还是用户界面,时间的处理都至关重要。C标准库提供了一套完整的工具来帮助我们处理时间相关的操作。本文将详细介绍几个时间操作函数的使用场景、代码实现以及它们在实际开发中…

42-5 应急响应之日志分析

一、Windows 系统日志排查 1)日志概述 在 Windows 2000 专业版、Windows XP 和 Windows Server 2003 中: 系统日志的位置为 C:\WINDOWS\System32\config\SysEvent.evt安全性日志的位置为 C:\WINDOWS\System32\config\SecEvent.evt应用程序日志的位置为 C:\WINNT\System32\c…

牛客周赛 Round 44VP

1.签到&#xff1a;https://ac.nowcoder.com/acm/contest/82526/A AC代码&#xff1a; #include<bits/stdc.h> using namespace std; int n; int main() {cin>>n;cout<<n/3; } 2.思维&#xff1a;https://ac.nowcoder.com/acm/contest/82526/B 就是判断最…

【漏洞复现】海康威视综合安防管理平台 iSecure Center applyCT fastjson 远程代码执行

0x01 漏洞名称 海康威视综合安防管理平台 iSecure Center applyCT fastjson 远程代码执行 0x02 漏洞影响 0x03 搜索引擎 app"HIKVISION-综合安防管理平台"0x04 漏洞详情 POST /bic/ssoService/v1/applyCT HTTP/1.1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Wi…

NASA数据集——阿尔法喷气式大气实验二氧化碳和甲烷数据

Alpha Jet Atmospheric eXperiment Carbon Dioxide and Methane Data 阿尔法喷气式大气实验二氧化碳和甲烷数据 简介 Alpha Jet Atmospheric eXperiment (AJAX) 是美国国家航空航天局艾姆斯研究中心与 H211, L.L.C. 公司的合作项目&#xff0c;旨在促进对加利福尼亚、内华达…

Kafka 实战 - Kafka Consumer 重置 Offset

在开发测试过程中&#xff0c;可能需要消费一段时间的消息&#xff0c;来验证数据的可靠性&#xff0c;这里需要消费者&#xff08;Consumer&#xff09;重置其消费的偏移量&#xff08;Offset&#xff09;。 以下是几种常用的方法来重置Kafka Consumer的Offset&#xff1a; …

vue+iview tabs context-menu 弹出框怎么修改样式

今天遇到一个需求说页面顶部的菜单右键弹出框离得有点远 代码是这样 <Tabs type"card" closable class"main-tags-col-tabs" v-model"activeTab" on-click"handleClickTag" :before-remove"handleBeforeRemove" capt…

什么是容器:从基础到进阶的全面介绍

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

libjpeg_example.txt

/* 示例.txt该文件说明了如何使用IJG代码作为子程序库读取或写入JPEG图像文件。你应该看看这段代码与文档文件 libjpeg.txt 结合使用。这段代码按原样不会做任何有用的事情&#xff0c;但它可能会有所帮助用于构建调用 JPEG 库的例程的骨架。我们以 JPEG 代码中使用的相同编码…

Java中的内部类及其用途

一、技术难点 在Java中&#xff0c;内部类是一个定义在另一个类内部的类。这种嵌套的结构带来了一些技术上的难点和挑战&#xff1a; 访问控制&#xff1a;内部类可以直接访问外部类的所有成员&#xff08;包括私有成员&#xff09;&#xff0c;但外部类不能直接访问内部类的…

Vue3实战笔记(44)—vue3组件的ref属性

文章目录 前言一、组件的ref用法总结总结 前言 之前学习过ref声明响应式对象&#xff0c;前几天读代码遇到了发懵的地方&#xff0c;详细学习了一下才发现&#xff0c;用法还有很多&#xff0c;遂总结一下ref的用法备忘。 一、组件的ref用法总结 Vue3 中的 ref 是一种创建响应…

【Linux 网络】网络基础(三)(网络层协议:IP 协议)

在复杂的网络环境中确定一个合适的路径。 一、TCP 与 IP 的关系 IP 层的核心作用是定位主机&#xff0c;具有将数据从主机 A 发送到主机 B 的能力&#xff0c;但是能力并不能保证一定能够做到&#xff0c;所以这时就需要 TCP 起作用了&#xff0c;TCP 可以通过超时重传、拥塞控…

【必备工具】gitee上传-保姆级教程

目录 1.gitee是什么 2.gitee怎么注册 ​编辑 3.gitee怎么提交代码 4.gitee的三板斧 Clone仓库 Q&A 1. Gitee 只有三板斧吗&#xff1f; 2. Git 教了&#xff0c;Gitee 上没有绿点怎么办&#xff1f; 3. 用户名和密码输入错误怎么办&#xff1f; 4. 操作时不小心…

【c++基础】和谐分组

题目描述 s 班共有 n 名学生&#xff0c;按照学号从 1 到的顺序每名学生的身高分别为 a[1],a[2]...a[n]。由于是新学期&#xff0c;s 班需要进行分组&#xff0c;分组的要求如下&#xff1a; 进行分组的组数不能超过 k。 每组的人的学号必须相邻。 由于身高差过大的人分在同一…

wordpress主题给网站增加一个版权声明区块代码分享

在数字化时代&#xff0c;网络上的信息传播变得越来越便捷&#xff0c;给人们生活和工作带来了极大的便利。然而&#xff0c;在这个过程中也产生了很多版权问题。为了更好地保护自己的版权&#xff0c;许多网站开始在其网页上添加版权声明。本文将探讨在网站上添加版权声明的重…

Gitee的原理及应用详解(二)

本系列文章简介&#xff1a; Gitee是一款开源的代码托管平台&#xff0c;是国内最大的代码托管平台之一。它基于Git版本控制系统&#xff0c;提供了代码托管、项目管理、协作开发、代码审查等功能&#xff0c;方便团队协作和项目管理。Gitee的出现&#xff0c;在国内的开发者社…