回答

收藏

从 io.Reader 到 Go 中的字符串

技术问答 技术问答 335 人阅读 | 0 人回复 | 2023-09-12

我有一个io.ReadCloser对象(来自一个http.Response对象)。* {% k& v- F, Y
将整个流转换成string对象最有效的方法是什么?4 h: \6 D3 x* x6 A
                                                                % [" ~( k0 n2 w: D/ t! W+ L
    解决方案:                                                               
% |0 G, R- o+ m+ o9 J                                                                编辑:+ h/ z5 E8 J# |* A. n2 w
从 1.10 开始,strings.Builder 存在。
1 Y4 H* B) a' U' O+ a5 c
    buf := new(strings.Builder)n,err := io.Copy(buf,r)// check errorsfmt.Println(buf.String())
    $ S* t# ]6 ]8 n* e( x
以下过时信息
1 t- u; N# i2 Q. C" d+ H9 H简短的答案是,它不高效,因为它需要完全复制字节数组才能转换成字符串。这是你想做的正确方法:
6 X+ f' v" i" z& a% y
    buf := new(bytes.Buffer)buf.ReadFrom(yourReader)s := buf.String() // Does a complete copy of the bytes in the buffer., d! Y. D& E' z1 U' c2 [* Y
这个副本是作为保护机制完成的。字符串是不可变的。如果可以, []byte 如果转换为字符串,可以更改字符串的内容。go 允许您使用 unsafe 禁用类型安全机制。unsafe 包的风险由你自己承担。我希望这个名字本身是一个足够好的警告。这就是我将如何使用 unsafe 这样做:' q  q# O9 w8 y
    buf := new(bytes.Buffer)buf.ReadFrom(yourReader)b := buf.Bytes()s := *(*string)(unsafe.Pointer(&b))
    : ?$ N$ y+ ^* R0 `9 U
嗯,你现在已经有效地将字节数组转换为字符串了。事实上,所有这些都是欺骗系统称之为字符串。这种方法有几个注意事项:8 ?2 a7 l. z" h; d, {9 {0 m% {
[ol]不能保证这将适用于所有 go 编译器。虽然这适用于 plan-9 gc 编译器,但它依赖于官方规范中没有提到的实现细节。您甚至不能保证它将适用于所有架构或不在 gc 改变。换句话说,这是个坏主意。  z/ ^3 v; W  O: c: K* U% ^2 t
字符串是可变的!如果您调用缓冲区,它将更改字符串。小心点。[/ol]我的建议是坚持官方方法。做副本不是那么昂贵,不值得不安全的罪恶。如果字符串太大,无法复制,则不应制成字符串。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则