在Golang中将文件编码为base64时,会丢失一个字节。

huangapple go评论73阅读模式
英文:

One byte is lost when encoding a file into base64 in Golang

问题

package main

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"io"
	"log"
	"os"
)

func b(name string) {
	f, err := os.Open(name)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	buf := new(bytes.Buffer)
	binval := base64.NewEncoder(base64.StdEncoding, buf)
	if _, err := io.Copy(binval, f); err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%s\n", buf.String()[buf.Len()-5:])
}

func main() {
	b("soccer.jpg")
	b("soccer2.jpg")
}

soccer.jpg
soccer2.jpg

输出:

bodqhrohro@debian:/tmp$ go run base64.go 
nuNf/
nuNf/

第一个文件与第二个文件相同,只是最后一个字节被删除了。它们生成了相同的base64字符串。有什么问题吗?

我在go1.15.9和go1.18.3上都遇到了这个问题。

英文:
package main

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"io"
	"log"
	"os"
)

func b(name string) {
	f, err := os.Open(name)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	buf := new(bytes.Buffer)
	binval := base64.NewEncoder(base64.StdEncoding, buf)
	if _, err := io.Copy(binval, f); err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%s\n", buf.String()[buf.Len()-5:])
}

func main() {
	b("soccer.jpg")
	b("soccer2.jpg")
}

soccer.jpg
soccer2.jpg

Output:

bodqhrohro@debian:/tmp$ go run base64.go 
nuNf/
nuNf/

The first file is identical to the second one just with the last byte cut out. They yield an identical base64 string. What's wrong?

I experience it with go1.15.9 and go1.18.3.

答案1

得分: 2

base64.NewEncoder 文档 中可以看到:

> 调用者必须关闭返回的编码器,以刷新任何部分写入的块。

所以:

binval.Close() // <- 添加这行

fmt.Printf("%s\n", buf.String()[buf.Len()-5:])

还可以参考文档中的 示例

// 在完成后必须关闭编码器,以刷新任何部分块。
// 如果你注释掉下面这行,最后一个部分块 "r" 将不会被编码。
encoder.Close()
英文:

From the base64.NewEncoder docs:

> the caller must Close the returned encoder to flush any partially
> written blocks.

So:

binval.Close() // <- add this

fmt.Printf("%s\n", buf.String()[buf.Len()-5:])

see also the doc's example:

// Must close the encoder when finished to flush any partial blocks.
// If you comment out the following line, the last partial block "r"
// won't be encoded.
encoder.Close()

huangapple
  • 本文由 发表于 2022年6月26日 03:09:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/72756661.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定