?yb? 2012-03-10 05:19 采纳率: 100%
浏览 506

在 Go 中从 io.Reader 到 string

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

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


  • 写回答

6条回答 默认 最新

  • 喵-见缝插针 2012-03-10 18:33

    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)
    s := buf.String() // Does a complete copy of the bytes in the buffer.

    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)
    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. 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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
  • 妄徒之命 2012-03-10 06:16

    I like the bytes.Buffer struct. I see it has ReadFrom and String methods. I've used it with a []byte but not an io.Reader.

  • YaoRaoLov 2012-03-10 08:14

    The most efficient way would be to always use []byte instead of string.

    In case you need to print data received from the io.ReadCloser, the fmt package can handle []byte, but it isn't efficient because the fmt implementation will internally convert []byte to string. In order to avoid this conversion, you can implement the fmt.Formatter interface for a type like type ByteSlice []byte.

  • 10.24 2012-03-10 21:36

    Answers so far haven't addressed the "entire stream" part of the question. I think the good way to do this is ioutil.ReadAll. With your io.ReaderCloser named rc, I would write,

    if b, err := ioutil.ReadAll(rc); err == nil {
        return string(b)
    } ...
  • 衫裤跑路 2018-07-01 18:27
    data, _ := ioutil.ReadAll(response.Body)
  • bug^君 2018-10-04 11:01
    func copyToString(r io.Reader) (res string, err error) {
        var sb strings.Builder
        if _, err = io.Copy(&sb, r); err == nil {
            res = sb.String()



  • ¥20 基于python进行多背包问题的多值编码
  • ¥15 相同型号电脑与配置,发现主板有一台貌似缺少了好多元器件似的,会影响稳定性和使用寿命吗?
  • ¥15 要求编写稀疏矩阵A的转置矩阵的算法
  • ¥15 编写满足以下要求的停车场管理程序,设停车场只有一个可停放n辆车的狭窄通道且只有一个大门可供车辆进出。
  • ¥15 C语言:数据子序列基础版
  • ¥20 powerbulider 导入excel文件,显示不完整
  • ¥15 用keil调试程序保证结果进行led相关闪烁
  • ¥15 paddle训练自己的数据loss降不下去
  • ¥20 用matlab的pdetool解决以下三个问题
  • ¥15 单个福来轮的平衡与侧向滑动是如何做到的?