每当我们在使用类似 io.Copy 和 ioutil.ReadAll 的工具时,比如我们正在从 http.Response 主体读入或者上传一个文件,我们会发现这些方法将一直堵塞,直到整个过程完成,哪怕耗时数十分钟甚至是小时——而且我们没有办法来查看进度,以及计算出完成所需剩余时间的估测值。

本文很长,不想深究瞅这里:这篇文章最终导向 progress 包,你可以在自己的项目中自由使用——https://github.com/machinebox/progress

考虑到 io.Reader 和 io.Writer 都是接口,我们可以封装它们并且拦截 Read 和 Write 方法,捕获实际已经通过它们的字节数。通过一些简单的数学计算,我们可以计算出已完成部分所占的比例。再多上一点数学计算,我们甚至可以估测整个过程还剩余多少时间,假设传输流是相对一致的话。

封装 Reader

一个新的 Reader 类型只需要包含另一个 io.Reader , 并且调用它的 Read 方法来获取返回前读到的字节数。为了保证 reader 可以在并发环境中安全使用(在这个例子中至关重要),我们可以使用 atomic.AddInt64 作为安全的计数器。

试试看你能不在自己写出 Writer 的计数部分,两者很类似。

由于方法 N 返回( 基于 atomic.LoadInt64 的安全调用)读取到的字节数,我们能在任意时刻使用另一个 goroutine 调用它,从而获取当前状况。

获取总共的字节数

为了计算百分比,我们需要知道总数是多少——我们预期读取多少字节?

上传文件时,我们能够利用操作系统获取文件大小。

在 HTTP 环境中,你可以借助下面这些代码来获取 Content-Length 报头值。

如果 Content-Length 报头是空的(这有可能),那么就无法判断进度或者估计剩余时间。

在其他状况下,你也会需要弄清楚如何获取字节总数。

计算百分比

现在我们可以计算已经被处理的字节数所占百分比:

我们需要把值转换为 float64 从而避免早期的向下取整。如果需要整数级精度的话我们依然可以把结果向下取整。

估算剩余时间

有一个非常简单的方法:求出读取 X 字节所需时间,然后乘以剩余的字节数。

举个例子,如果耗时 10 秒完成了 50% 的操作,那么就可以假设仍需要 10 秒来完成整个任务;总耗时 20 秒。

这并不绝对精确,但大多时候都可以给出一个可采用的倒计时。

代码就在下面,但不需要担心你可能理解不了 —— 阅读我们的 package 下面的详细信息可以帮到你。

  • ratio — 已经完成字节数所占的百分比
  • past — 从开始到现在的耗时
  • total — 基于已完成的百分比 ratio 和相应耗费的时间,从而得出的预计总耗时
  • estimated — 预测的结束时间点
  • duration — 预测距离完成还需要耗费的时间

浏览 progess 包

我们热爱开源,所以我们封装了所有代码到一个 package 中以方便您的使用。

它也支持 io.EOF 和其他你知道的可能会在操作时发生的错误。

小助手

我们还添加了一个小助手,它可以给你一个进度上的 go channel 来周期性报告。 你可以开启一个新的 goroutine 并打印进度,或更新进度,这取决于您的用例。

该 channel 会周期性的返回一个 Progress 结构体,该结构体有下列几个方法帮助你了解细节。

  • Percent — 获取操作完成的百分比
  • Estimated — time.Time 表示预期操作结束的时间点
  • Remaining — 一个 time.Duration 变量标识剩余时间

channel 会在几种情况下被关闭,例如操作已完成,或者操作被取消。

点击文档 可以获取 API 的最新详细目录

示例

我们创建了一个 example file downloader 来演示该 package 如何使用。

还有什么?

请尝试我们的开源项目,提出问题,报告议题,提交重要的 PR 。

什么是 Machine Box ?

Machine Box 把先进的机器学习技术放到 Docker 容器中,以便让开发人员可以更轻松的集成

自然语言处理,面部检测,对象识别等技术到你自己的应用中。

该技术是按比例构建,所以当你的应用扩大时只需要添加更多同级的 box 。噢,而且它比云服务廉价的多(可能还会更好)……而且你的数据也不会离开你自己的基础设备。

玩一玩 , 并且请告知我们您宝贵的意见。


正在从“vetur”获取代码操作_长时间运行 io.Reader 和 io.Writer 操作测算进度和估算剩余时间...相关推荐

  1. python怎么暂停运行_如何暂停长时间运行的循环?

    我有一个关于正在运行的程序的长时间问题.在本例中,我将使用Python,但它可以用于任何编程语言.在 比方说我想把所有的数字加起来,比如说10亿results = [] for i in range( ...

  2. game module 停止运行_恒温摇床长时间运行的注意事项

    2020年10月30日 11:47   来源: 杭州川一实验仪器有限公司    >>进入该公司展台 产品简介 恒温摇床具有不锈钢万用夹具.数显控温.无级调速和良好的热循环功能,是一种多用途 ...

  3. struts2 拦截器_Struts2 execAndWait拦截器示例,用于长时间运行的动作

    struts2 拦截器 Sometimes we have long running actions where user will have to wait for final result. In ...

  4. go 获取内核个数_图解Go运行时调度器

    多goroutines形式的Go并发是编写现代并发软件的一种非常方便的方法,但是您的Go程序是如何高效地运行这些goroutines的呢? 在这篇文章中,我们将深入Go运行时底层,从设计角度了解Go运 ...

  5. rd 删除 长目录_长时间的反馈循环如何伤害您的rd

    rd 删除 长目录 I've been a part of the medical software world for a number of years now, and let me tell ...

  6. 更新失败无法连接更新服务器未响应,逆水寒客户端更新失败_长时间停滞未响应相关问题解答[图]...

    逆水寒每周四就会进行例行维护,很多小伙伴的电脑在每次更新中都会出现各种各样的相关问题,像一些基本的逆水寒客户端更新失败,长时间停滞未响应相关问题,我们一起来看看官方是如何解答的吧! 一.逆水寒客户端更 ...

  7. 蓝牙耳机音量大解决办法_长时间使用蓝牙耳机的危害这么大?我们到底该选什么蓝牙耳机呢?...

    蓝牙耳机避免了耳机线缠结,使人活动更自由,给人们带来了更加方便.舒适的听觉体验.但近日,英国<每日邮报>刊文表示,蓝牙耳机可能会危害人体健康. 美国加州大学伯克利分校公共健康教授乔尔·莫斯 ...

  8. java io流操作_十个Demo进行讲解Java中IO流的常用操作~

    好久不见的IO流 对IO流的学习,我记得还是初学Java基础的时候,后来找工作过程中经常看到有些招聘信息中写到熟悉IO流,现在想想IO流,真的是一脸懵逼,不说这么多废话了,IO流这次好好整理一下. 说 ...

  9. 长时间运行app,产生anr

    app需要实时的更新当前的地址位置信息,在位置监听中进行显示出来,包括经纬的转换,距离目标,在测试几个小时内没有问题,但是在12个小时以上就出现了界面点击无响应. 解决办法 调试发现监听中耗时10ms ...

最新文章

  1. C# 正则表达式小结
  2. 垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
  3. ADO.NET Entity Framework建模和映射(实体框架)
  4. C4C和Marketing Cloud的lead以及activity的replication
  5. Java之HashMap、Hashtable、LinkedHashMap、TreeMap、ConcurrentHashMap简单的区别
  6. 对象存储 OSS > 产品简介 > 什么是对象存储OSS
  7. 佛系青蛙外挂横行,20 元可买 21 亿无限三叶草
  8. spring boot demo(spring jdbc访问数据)
  9. php编写一个学生类_PHP 结合 Boostrap 结合 js 实现学生列表删除编辑及搜索功能
  10. cdn搭建原理_CDN运行过程四大要点,附技术原理图解,智能DNS解析
  11. KEIL工程文件打不开
  12. [点点搬家]与Perl厮混后感觉嘚儿嘚儿的
  13. AR502H-CN开发笔记18:快速建立开发环境
  14. OCJP(1Z0-851) 模拟题分析(一)
  15. java学习第183天,javaWeb学习第42天,复习第19天;p240-245(08/16)-6h
  16. 笛卡儿积、左连接、右连接
  17. Java语言的File类总结
  18. 本地ISO文件作为YUM源
  19. 利用Python做新能源公司股票分析(可视化)
  20. 漏洞挖掘——域名收集

热门文章

  1. idea代码补全声明代码_用了这么多年idea,竟然不知道这些代码补全功能
  2. 一个form 如何做两次提交_如何做一个自信魅力的女人
  3. python能制作游戏吗_没有Python不能做的游戏,这些游戏都可以做
  4. linux远程windows执行cmd,Linux服务器远程连接window服务器并执行cmd命令
  5. java实现复制粘贴的计算器_软帝学院教你用java编写计算器(三)
  6. mysql远程授权格式_MySQL远程访问授权
  7. php数组交集方法,PHP获得数组交集与差集的方法
  8. Java容器解析——HashMap
  9. linux mysql 备份脚本_linux 之mysql备份脚本
  10. oracle内存表与临时表,Oracle 临时表之临时表空间组(TTG)