我正在尝试解码非常大的base64编码的字符串,可能以兆字节为单位。我想对base64进行解码,而不分配类似大小的输出数组。我想对字符串进行解码,然后重新使用输入字符串的基础存储。
有可能吗?
答案 0 :(得分:3)
为什么要使用base64编码的不可变string
?从[]byte
转换为string
是浪费的。您应该具有以base64编码的可变[]byte
。
例如,
package main
import (
"encoding/base64"
"fmt"
)
func main() {
enc := base64.StdEncoding
// Test data
b := make([]byte, 16)
for i := range b {
b[i] = byte(i)
}
fmt.Println(len(b), b)
b64 := make([]byte, enc.EncodedLen(len(b)))
enc.Encode(b64, b)
// Decode base64 without extra array allocations
fmt.Printf("%d %q\n", len(b64), b64)
d := b64
n, err := enc.Decode(d, b64)
d = d[:n:n]
if err != nil {
panic(err)
}
fmt.Println(len(d), d)
}
游乐场:https://play.golang.org/p/BfyaXjv_vwS
输出:
16 [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
24 "AAECAwQFBgcICQoLDA0ODw=="
16 [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
注意:缓冲区的安全共享可能取决于实现。编写测试以确保它继续安全。
答案 1 :(得分:-2)
是的,可以使用不安全的代码。正如已经建议的,寻找另一种选择,但是...
也许您被卡住了,因为您得到了一个字符串(您知道该字符串不在只读内存中),并且您无法访问字节片。如果您小心一点,可以修改类似以下的字符串:
// build a string (string literals are kept in read-only memory)
sb := strings.Builder{}
sb.WriteString("abc")
s := sb.String()
b := *(*struct {p *[999999999]byte; length int})(unsafe.Pointer(&s))
// Be very careful not to write past the end of the string
b.p[b.length-1]++ // modify the last byte
同样,我不能过分强调不安全的代码是危险的,因此您需要非常小心。例如,请确保您不要在字符串的末尾写过文字,并理解为什么字符串是不可变的。