Home > Software engineering >  GOLANG Base64 Encode and Decode size mismatched for large files
GOLANG Base64 Encode and Decode size mismatched for large files

Time:12-06

When I am trying to do base64 encode and decode for large files using golang, I am getting byte length missmatched between original and decoded file.

During my testing text file mismatched(1 byte) new line, and with binary file mismatched (2 bytes).

What could be cause missing of these bytes?

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
}

CodePudding user response:

you don't Close() the encoder so it doesn't flush all the data. from the docs (emphasis mine):

func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser

NewEncoder returns a new base64 stream encoder. Data written to the returned writer will be encoded using enc and then written to w. Base64 encodings operate in 4-byte blocks; when finished writing, the caller must Close the returned encoder to flush any partially written blocks.

I also quote the example from the docs which has a nice comment:

package main

import (
    "encoding/base64"
    "os"
)

func main() {
    input := []byte("foo\x00bar")
    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()
}
  • Related