从 io.Reader 到 Go 中的字符串 [英] From io.Reader to string in Go

查看:36
本文介绍了从 io.Reader 到 Go 中的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 io.ReadCloser 对象(来自 http.Response 对象).

I have an io.ReadCloser object (from an http.Response object).

将整个流转换为 string 对象的最有效方法是什么?

What's the most efficient way to convert the entire stream to a string object?

推荐答案

从 1.10 开始,strings.Builder 就存在了.示例:

Since 1.10, strings.Builder exists. Example:

buf := new(strings.Builder)
n, err := io.Copy(buf, r)
// check errors
fmt.Println(buf.String())

<小时>

以下信息已过时

简短的回答是它效率不高,因为转换为字符串需要对字节数组进行完整的复制.这是做您想做的事情的正确(非有效)方法:

The short answer is that it it will not be efficient because converting to a string requires doing a complete copy of the byte array. Here is the proper (non-efficient) way to do what you want:

buf := new(bytes.Buffer)
buf.ReadFrom(yourReader)
s := buf.String() // Does a complete copy of the bytes in the buffer.

这个副本是作为一种保护机制完成的.字符串是不可变的.如果可以将 []byte 转换为字符串,则可以更改字符串的内容.但是,go 允许您使用 unsafe 包禁用类型安全机制.使用 unsafe 包的风险由您自己承担.希望这个名字本身就是一个足够好的警告.以下是我使用 unsafe 的方法:

This copy is done as a protection mechanism. Strings are immutable. If you could convert a []byte to a string, you could change the contents of the string. However, go allows you to disable the type safety mechanisms using the unsafe package. Use the unsafe package at your own risk. Hopefully the name alone is a good enough warning. Here is how I would do it using unsafe:

buf := new(bytes.Buffer)
buf.ReadFrom(yourReader)
b := buf.Bytes()
s := *(*string)(unsafe.Pointer(&b))

我们开始了,您现在已经有效地将字节数组转换为字符串.实际上,所有这些都是欺骗类型系统将其称为字符串.这种方法有几个注意事项:

There we go, you have now efficiently converted your byte array to a string. Really, all this does is trick the type system into calling it a string. There are a couple caveats to this method:

  1. 不能保证这将适用于所有 go 编译器.虽然这适用于 plan-9 gc 编译器,但它依赖于官方规范中未提及的实现细节".您甚至不能保证这将适用于所有架构或不会在 gc 中更改.换句话说,这是个坏主意.
  2. 那个字符串是可变的!如果您对该缓冲区进行任何调用,它更改字符串.要非常小心.
  1. There are no guarantees this will work in all go compilers. While this works with the plan-9 gc compiler, it relies on "implementation details" not mentioned in the official spec. You can not even guarantee that this will work on all architectures or not be changed in gc. In other words, this is a bad idea.
  2. That string is mutable! If you make any calls on that buffer it will change the string. Be very careful.

我的建议是坚持官方方法.做一个副本并不昂贵,也不值得不安全的弊端.如果字符串太大而无法复制,则不应将其制作成字符串.

My advice is to stick to the official method. Doing a copy is not that expensive and it is not worth the evils of unsafe. If the string is too large to do a copy, you should not be making it into a string.

这篇关于从 io.Reader 到 Go 中的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆