Json Encoding#

Let write some struct to json file with indent.

func writeDataToJsonFile() {
// create a list of struct
books := []struct {
Name string `json:"Name"`
Author string `json:"Author"`
}{
{"The Great Gatsby", "F. Scott Fitzgerald"},
{"The Catcher in the Rye", "J. D. Salinger"},
{"The Grapes of Wrath", "John Steinbeck"},
{"The Scroll of Tom Sawyer", "Mark Twain"},
{"The Adventures of Huckleberry Finn", "Mark Twain"},
{"The Adventures of Tom Sawyer", "Mark Twain"},
{"The Adventures of Tom Sawyer", "Mark Twain"},
{"The Adventures of Tom Sawyer", "Mark Twain"},
}
// json encode with ident
data, error := json.MarshalIndent(books, "", "")
if error != nil {
fmt.Println(error)
}
// create a file
file, error := os.Create("log.json")
if error != nil {
fmt.Println(error)
}
defer file.Close()
// write data to file json
file.Write(data)
}

Write Bytes to File#

Let write bytes to a file

func writeBytesToFile() {
// create a file
file, error := os.Create("log.txt")
if error != nil {
fmt.Println(error)
}
defer file.Close()
var bytes = []byte{
0x47, // G
0x4f, // O
0x20, // <space>
0x20, // <space>
0x20, // <space>
0x50, // P
0x4c, // L
0x45, // E
0x53, // S
}
error = os.WriteFile("log.txt", bytes, 0644)
if error != nil {
fmt.Println(error)
}
}

Gob Encoding#

  • binary encoding for fixed-length data
  • gob encoding for variable length data
package main
import (
"bytes"
"encoding/binary"
"encoding/gob"
"fmt"
"testing"
)
func TestFixedSizeData(t *testing.T) {
var buffer bytes.Buffer
book := struct{Age int16}{128}
error := binary.Write(&buffer, binary.BigEndian, book)
if error != nil {
fmt.Println("binary.Write failed:", error)
}
fmt.Println(buffer.Bytes())
}
func TestVariableSizeData(t *testing.T) {
var buffer bytes.Buffer
book := struct{Name string}{"Hello Hai Tran"}
encoder := gob.NewEncoder(&buffer)
error := encoder.Encode(book)
if error != nil {
fmt.Println(error)
}
fmt.Println(buffer.Bytes())
}

Read File Line by Line#

Package bufio implements buffered I/O. It wraps an io.Reader or io.Writer object, creating another object (Reader or Writer) that also implements the interface but provides buffering and some help for textual I/O.

func readFileLineByLine(filename string) {
// open file
file, error := os.Open(filename)
if error != nil {
fmt.Println(error)
}
// create a buffer io reader
reader := bufio.NewReader(file)
// read line by line via the reader
for {
line, err := reader.ReadString('\n')
if err == io.EOF {
fmt.Println("End of file")
break
}
if err != nil {
fmt.Println(err)
return
}
fmt.Print(line)
}
}

IO Reader and Writer Interface#

Reader interface. This data source could be anything — a file, a network connection, or even just a plain string. But io.Reader doesn’t care about where the data is coming from. All it knows is that there’s some data, and its job is to copy that data into the slice you gave it.

type Reader interface {
Read(p []byte) (n int, err error)
}

Writer interface

type Writer interface {
Write(p []byte) (n int, err error)
}

Reference#

  • Go I/O Readers, Writers, and Data in Motion