DEV Community

chris
chris

Posted on

Append data to JSON in Go

Working on some projects, I needed to write continuous data to JSON files in Go. So as I found various tutorial but none really gave me what I wanted, here is mine!

Get the files ready

The last thing you want is panics on missing files, so you need to check if the file exists first (here is the example I used). I tweaked it a bit more so I could create the file if it didn't exist.

func checkFile(filename string) error {
    _, err := os.Stat(filename)
        if os.IsNotExist(err) {
            _, err := os.Create(filename)
                if err != nil {
                    return err
                }
        }
        return nil
}

Enter fullscreen mode Exit fullscreen mode

I know we could return the file itself, but I didn't really needed it in this case.

Save the Marshall Ryan

I am not entirely sure I understand marshalling completely, I have to confess. What I know is that the Go handle is ready the bytes in an array and you need to send it to a receiving structure to be able to have it human-readable.

And of course the same way back to write to it.

type MyStruct struct {
    StructData string `json:"StructData"`
}

func main() {
    filename := "myFile.json"
    err := checkFile(filename)
    if err != nil {
        logrus.Error(err)
    }

    file, err := ioutil.ReadFile(filename)
    if err != nil {
        logrus.Error(err)
    }

    data := []MyStruct{}

    // Here the magic happens!
    json.Unmarshal(file, &data)
}

Enter fullscreen mode Exit fullscreen mode

Now we can work and build more structures to our JSON file.


// MyStruct is an example structure for this program.
type MyStruct struct {
    StructData string `json:"StructData"`
}

func main() {

    [...]
    newStruct := &MyStruct{
        StructData: "peanut",
    }

    data = append(data, *newStruct)

    // Preparing the data to be marshalled and written.
    dataBytes, err := json.Marshall(data)
    if err != nil {
        logrus.Error(err)
    }

    err = ioutil.WriteFile(filename, dataBytes, 0644)
    if err != nil {
        logrus.Error(err)
    }
}

Enter fullscreen mode Exit fullscreen mode

That does the work! What are your techniques to write to JSON file and append new data to it?

Here is the whole code:

package main

import (
    "encoding/json"
    "io/ioutil"
    "os"

    "github.com/sirupsen/logrus"
)

// MyStruct is an example structure for this program.
type MyStruct struct {
    StructData string `json:"StructData"`
}

func main() {
    filename := "myFile.json"
    err := checkFile(filename)
    if err != nil {
        logrus.Error(err)
    }

    file, err := ioutil.ReadFile(filename)
    if err != nil {
        logrus.Error(err)
    }

    data := []MyStruct{}

    // Here the magic happens!
    json.Unmarshal(file, &data)

    newStruct := &MyStruct{
        StructData: "peanut",
    }

    data = append(data, *newStruct)

    // Preparing the data to be marshalled and written.
    dataBytes, err := json.Marshal(data)
    if err != nil {
        logrus.Error(err)
    }

    err = ioutil.WriteFile(filename, dataBytes, 0644)
    if err != nil {
        logrus.Error(err)
    }
}

func checkFile(filename string) error {
    _, err := os.Stat(filename)
    if os.IsNotExist(err) {
        _, err := os.Create(filename)
        if err != nil {
            return err
        }
    }
    return nil
}


Enter fullscreen mode Exit fullscreen mode

Latest comments (5)

Collapse
 
radictionary profile image
Radin

3 years later, and this post is still very helpful. Thanks :)

Collapse
 
chriscoyier profile image
Chris Coyier

Looks like a json.Marshall snuck in there (two l's) which is wrong I'm pretty sure.

Collapse
 
anonyma profile image
Anonyma

Straight to the point, thank you!

Collapse
 
icesofty profile image
Florian

Thank you, Chris. That was useful

Collapse
 
evilcel3ri profile image
chris

Happy to help!