#go #base64
#Вперед #base64
Вопрос:
Когда я пытаюсь выполнить кодирование и декодирование base64 для больших файлов с помощью golang, я получаю несоответствие длины байта между исходным и декодированным файлом.
Во время моего тестирования текстовый файл не соответствовал (1 байт) новой строке, а двоичный файл не соответствовал (2 байта).
Что может быть причиной отсутствия этих байтов?
package main
import (
"encoding/base64"
"io"
"os"
"log"
)
func Encode(infile, outfile string) error {
input, err := os.Open(infile)
if err != nil {
return err
}
// Close input file
defer input.Close()
// Open output file
output, err := os.Create(outfile)
if err != nil {
return err
}
// Close output file
defer output.Close()
encoder := base64.NewEncoder(base64.StdEncoding, output)
l, err := io.Copy(encoder, input)
if err!=nil {
log.Printf("Failed to encode file:%v",err)
return err
} else {
log.Printf("Wrote %v bytes",l)
}
return nil
}
func Decode(infile, outfile string) error {
input, err := os.Open(infile)
if err != nil {
return err
}
// Close input file
defer input.Close()
// Open output file
output, err := os.Create(outfile)
if err != nil {
return err
}
// Close output file
defer output.Close()
decoder := base64.NewDecoder(base64.StdEncoding, input)
l, err := io.Copy(output, decoder)
if err!=nil {
log.Printf("Failed to encode file:%v",err)
return err
} else {
log.Printf("Wrote %v bytes",l)
}
return nil
}
Ответ №1:
вы этого не Close()
encoder
делаете, поэтому он не удаляет все данные. из документов (выделение мое):
функция NewEncoder(enc *Encoding, w io.Запись) ввод-вывод.WriteCloser
NewEncoder возвращает новый кодировщик потока base64. Данные, записанные на возвращенный writer, будут закодированы с использованием enc, а затем записаны в w. Кодировки Base64 работают в 4-байтовых блоках; по завершении записи вызывающий должен закрыть возвращенный кодировщик, чтобы очистить все частично записанные блоки.
Я также цитирую пример из документов, в котором есть хороший комментарий:
package main
import (
"encoding/base64"
"os"
)
func main() {
input := []byte("foox00bar")
encoder := base64.NewEncoder(base64.StdEncoding, os.Stdout)
encoder.Write(input)
// 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()
}