go 中 ioutil.ReadAll 的替代方案?

2024-01-27

对于我正在制作的程序,此函数作为 for 循环中的 goroutine 运行,具体取决于传入的 url 数量(没有设定数量)。

func makeRequest(url string, ch chan<- string, errors map[string]error){
  res, err := http.Get(url)
  if err != nil {
    errors[url] = err
    close(ch)
    return
  }

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)
  ch <- string(body)
}

必须使用响应的整个正文,因此 ioutil.ReadAll 似乎非常适合,但对可以传入的 url 数量没有限制,而且 ReadAll 的性质是它全部存储在内存中,因此开始感觉不那么重要就像金票一样。我对 Go 相当陌生,所以如果你决定回答,如果你能在你的解决方案背后给出一些解释,我将不胜感激!


当我学习如何使用 Go 时,我得到的一个见解是,ReadAll 对于大读者来说通常效率低下,并且就像您的情况一样,它会受到非常大的任意输入的影响,并且可能会泄漏内存。当我开始时,我曾经这样进行 JSON 解析:

data, err := ioutil.ReadAll(r)
if err != nil {
    return err
}
json.Unmarshal(data, &v)

然后,我学到了一种更有效的解析 JSON 的方法,那就是简单地使用Decoder type.

err := json.NewDecoder(r).Decode(&v)
if err != nil {
    return err
}

这不仅更简洁,而且在内存和时间方面都更加高效:

  • 解码器不必分配一个巨大的字节片来容纳数据读取 - 它可以简单地重用一个微小的缓冲区,该缓冲区将用于Read方法获取所有数据并解析它。这节省了大量的分配时间并消除了 GC 的压力
  • JSON 解码器可以在第一个数据块进入时立即开始解析数据 - 它不必等待所有内容完成下载。

现在,当然你的问题与 JSON 无关,但这个例子很有用,可以说明如果你可以使用Read直接一次解析数据块,就可以了。特别是对于 HTTP 请求,解析比读取/下载更快,因此这可能会导致解析的数据在请求正文完成到达时几乎立即准备就绪。

就您而言,您目前似乎并未实际对数据进行任何处理,因此没有太多建议可以专门帮助您。但是io.Readerio.Writer接口在 Go 中相当于 UNIX 管道,因此您可以在许多不同的地方使用它们:

将数据写入文件:

f, err := os.Create("file")
if err != nil {
    return err 
}
defer f.Close()

// Copy will put all the data from Body into f, without creating a huge buffer in memory
// (moves chunks at a time)
io.Copy(f, resp.Body)

将所有内容打印到标准输出:

io.Copy(os.Stdout, resp.Body)

将响应的正文通过管道传输到请求的正文:

resp, err := http.NewRequest("POST", "https://example.com", resp.Body)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

go 中 ioutil.ReadAll 的替代方案? 的相关文章

  • 我首次设置 AWS EB 时创建的默认安全组是什么?

    我对几个组所扮演的角色感到困惑 这些组似乎已自动添加到我的 AWS 安全组列表中 并以我收集的默认配置进行连接 并且想知道它们是如何工作的 以及它们的安全性如何 改变 具体来说 有三个神秘之处 launch wizard 1其中有一条入站规
  • 在 Ubuntu 12.04 上的 Apache 上配置 SVN 服务器

    我正在尝试通过 HTTP 访问现有的 Subversion 服务器 我的dav svn conf文件看起来像
  • 使用 crypto/ssh 的 golang scp 文件

    我正在尝试通过 ssh 下载远程文件 以下方法在 shell 上运行良好 ssh hostname tar cz opt local folder gt folder tar gz 然而 golang 上的相同方法在输出工件大小方面存在一些
  • 取消用户特定的 goroutine [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个应用程序 网络应用程序 允许用户使用 twitter oauth 登录并提供自动推文删除功能 用户登录到 Web 应用程序后
  • 您可以从 AuthorizeAttribute 返回 HTTP 响应而不引发异常吗?

    我在各种控制器上使用 AuthorizeAttribute 可能需要根据请求本身的某些属性返回 403 或 429 请求过多 我完全在自定义 OnAuthorization 实现中实现了它 然后在必要时抛出一个带有适当响应代码的新 Http
  • Go 中的 WebP 编码器/解码器

    是否有一个完整的 WebP 编码器和解码器与当前每周 或可分叉 兼容 它的速度与标准 png 相当吗 这个人在 GitHub 上有一个包 其中包含 WebP 的编码器和解码器 https github com chai2010 webp h
  • Golang 按位运算以及一般字节操作

    我有一些 C 代码 可以对字节执行一些按位运算 我正在尝试在 golang 中做同样的事情 但遇到了困难 C 中的示例 byte a c byte data int j c data j c byte c j c a c 0xFF c 0x
  • 在 haskell 中处理 IO 与纯代码

    我正在编写一个shell脚本 我在haskell中的第一个非示例 它应该列出一个目录 获取每个文件大小 进行一些字符串操作 纯代码 然后重命名一些文件 我不确定我做错了什么 所以有两个问题 我应该如何安排这样的程序中的代码 我有一个具体问题
  • 我们如何在 Golang 中组合多个错误字符串?

    我是 golang 新手 我的应用程序需要在循环中返回多个错误 稍后需要组合并作为单个错误字符串返回 我无法使用字符串函数来组合错误消息 在返回之前可以使用什么方法将这些错误合并为一个错误 package main import fmt s
  • 视频第一帧

    我正在创建一个单页应用程序 后端使用 Golang 前端使用 javascript 我想找到一种使用 Golang 获取视频第一帧的方法 首先 我将 mp4 视频文件上传到服务器 它保存在服务器上 有没有办法使用 Golang 获取该视频的
  • Golang 基础知识 struct 和 new() 关键字

    我正在学习 golang 当我阅读描述结构的章节时 我遇到了初始化结构的不同方法 p1 passport var p2 passport p3 passport Photo make byte 0 0 Name Scott Surname
  • Angular JS 在调用新的 $http 之前取消 $http 调用

    在 Angular JS 1 1 5 中 您可以取消之前启动的 http 调用 这两个link1 https stackoverflow com questions 16962232 in angularjs how to stop ong
  • HTTP部分上传、断点续传的标准方法

    我正在开发 http 客户端 服务器框架 并寻找处理部分上传的正确方法 与使用带有 Range 标头的 GET 方法进行下载相同 但是 HTTP PUT 并不打算恢复 据我所知 PATCH 方法不接受 Range 标头 有没有办法通过 HT
  • 完全删除使用“go get”安装的软件包?

    我正在使用 Go 1 13 1 最新版本 我正在尝试完全删除我安装的软件包go get来自 GitHub 这go clean i
  • 如何从非英语字符串解析go中的月份

    我想将以下字符串解析为 go 中的日期 This item will be released on March 9 2014 我跟着this https stackoverflow com questions 14106541 go par
  • HTTP代理服务器

    我开始研究一个用 C 编写的非常基本的 HTTP 代理服务器 Edit 只是转发我的请求的东西 此时我很难理解如何继续 任何帮助都会有益的 看一眼micro proxy http acme com software micro proxy
  • 返回重定向作为对 Ajax(fetch、XHR 等)请求的响应

    如果浏览器收到对 ajax 请求的重定向响应 会发生什么 如果浏览器收到对 ajax 请求的重定向响应 会发生什么 如果服务器发送重定向 又名 302 响应加上 Location 标头 浏览器将自动遵循重定向 对此的回应second请求 假
  • 使用覆盖率信息测试 Go 中的 os.Exit 场景 (coveralls.io/Goveralls)

    这个问题 如何在 Go 中测试 os exit 场景 https stackoverflow com questions 26225513 how to test os exit scenarios in go 以及其中得票最高的答案 列出
  • 从 HTTP 登录到 HTTPS

    我的网站默认使用 HTTP 我确实有一个启用 HTTPS 的证书 但只有其上的某些区域强制建立安全连接 登录是通过 Ajax 处理的 我想开始使用 SSL 即使请求来自 HTTP 我尝试强制请求的地址具有 HTTPS 并且它完美地回复 然而
  • 有没有办法使用 ASP.NET 在用户离开页面时始终运行某些服务器端代码?

    我想知道当用户离开 ASP NET 中的页面时是否有任何方法可以始终运行一些服务器端代码 页面卸载事件不好 因为如果有人单击链接 则不会调用该事件 理想情况下 即使用户关闭浏览器 我也希望代码能够运行 我怀疑我所问的问题是不可能的 但问一下

随机推荐