Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write Struct to Json File using Struct Fields (not json keys)

Tags:

json

go

How can I read a json file into a struct, and then Marshal it back out to a json string with the Struct fields as keys (rather than the original json keys)?

(see Desired Output to Json File below...)

Code:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
)

type Rankings struct {
    Keyword  string `json:"keyword"`
    GetCount uint32 `json:"get_count"`
    Engine   string `json:"engine"`
    Locale   string `json:"locale"`
    Mobile   bool   `json:"mobile"`
}

func main() {
    var jsonBlob = []byte(`
        {"keyword":"hipaa compliance form", "get_count":157, "engine":"google", "locale":"en-us", "mobile":false}
    `)
    rankings := Rankings{}
    err := json.Unmarshal(jsonBlob, &rankings)
    if err != nil {
        // nozzle.printError("opening config file", err.Error())
    }

    rankingsJson, _ := json.Marshal(rankings)
    err = ioutil.WriteFile("output.json", rankingsJson, 0644)
    fmt.Printf("%+v", rankings)
}

Output on screen:

{Keyword:hipaa compliance form GetCount:157 Engine:google Locale:en-us Mobile:false}

Output to Json File:

{"keyword":"hipaa compliance form","get_count":157,"engine":"google","locale":"en-us","mobile":false}

Desired Output to Json File:

{"Keyword":"hipaa compliance form","GetCount":157,"Engine":"google","Locale":"en-us","Mobile":false}
like image 684
Joe Bergevin Avatar asked Jul 16 '14 00:07

Joe Bergevin


People also ask

Can you write JSON file using Go language?

Reading and Writing JSON Files in GoIt is actually pretty simple to read and write data to and from JSON files using the Go standard library. For writing struct types into a JSON file we have used the WriteFile function from the io/ioutil package. The data content is marshalled/encoded into JSON format.

What is JSON Unmarshalling?

To unmarshal a JSON array into a slice, Unmarshal resets the slice length to zero and then appends each element to the slice. As a special case, to unmarshal an empty JSON array into a slice, Unmarshal replaces the slice with a new empty slice.

How do I use Unmarshal JSON?

To parse JSON, we use the Unmarshal() function in package encoding/json to unpack or decode the data from JSON to a struct. Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. Note: If v is nil or not a pointer, Unmarshal returns an InvalidUnmarshalError.

How do I write a struct file in Golang?

The struct values are initialized and then serialize with the json. MarshalIndent() function. The serialized JSON formatted byte slice is received which then written to a file using the ioutil. WriteFile() function.


2 Answers

If I understand your question correctly, all you want to do is remove the json tags from your struct definition.

So:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
)

type Rankings struct {
    Keyword  string 
    GetCount uint32 
    Engine   string 
    Locale   string 
    Mobile   bool   
}

func main() {
    var jsonBlob = []byte(`
        {"keyword":"hipaa compliance form", "get_count":157, "engine":"google", "locale":"en-us", "mobile":false}
    `)
    rankings := Rankings{}
    err := json.Unmarshal(jsonBlob, &rankings)
    if err != nil {
        // nozzle.printError("opening config file", err.Error())
    }

    rankingsJson, _ := json.Marshal(rankings)
    err = ioutil.WriteFile("output.json", rankingsJson, 0644)
    fmt.Printf("%+v", rankings)
}

Results in:

{Keyword:hipaa compliance form GetCount:0 Engine:google Locale:en-us Mobile:false}

And the file output is:

{"Keyword":"hipaa compliance form","GetCount":0,"Engine":"google","Locale":"    en-us","Mobile":false}

Running example at http://play.golang.org/p/dC3s37HxvZ

Note: GetCount shows 0, since it was read in as "get_count". If you want to read in JSON that has "get_count" vs. "GetCount", but output "GetCount" then you'll have to do some additional parsing.

See Go- Copy all common fields between structs for additional info about this particular situation.

like image 83
Momer Avatar answered Sep 28 '22 00:09

Momer


An accourance happened by just using json.Marshal() / json.MarshalIndent(). It overwrites the existing file, which in my case was suboptimal. I just wanted to add content to current file, and keep old content.

This writes data through a buffer, with bytes.Buffer type.

This is what I gathered up so far:

package srf

import (
    "bytes"
    "encoding/json"
    "os"
)

func WriteDataToFileAsJSON(data interface{}, filedir string) (int, error) {
    //write data as buffer to json encoder
    buffer := new(bytes.Buffer)
    encoder := json.NewEncoder(buffer)
    encoder.SetIndent("", "\t")

    err := encoder.Encode(data)
    if err != nil {
        return 0, err
    }
    file, err := os.OpenFile(filedir, os.O_RDWR|os.O_CREATE, 0755)
    if err != nil {
        return 0, err
    }
    n, err := file.Write(buffer.Bytes())
    if err != nil {
        return 0, err
    }
    return n, nil
}

This is the execution of the function, together with the standard json.Marshal() or json.MarshalIndent() which overwrites the file

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"

    minerals "./minerals"
    srf "./srf"
)

func main() {

    //array of Test struct
    var SomeType [10]minerals.Test

    //Create 10 units of some random data to write
    for a := 0; a < 10; a++ {
        SomeType[a] = minerals.Test{
            Name:   "Rand",
            Id:     123,
            A:      "desc",
            Num:    999,
            Link:   "somelink",
            People: []string{"John Doe", "Aby Daby"},
        }
    }

    //writes aditional data to existing file, or creates a new file
    n, err := srf.WriteDataToFileAsJSON(SomeType, "test2.json")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("srf printed ", n, " bytes to ", "test2.json")

    //overrides previous file
    b, _ := json.MarshalIndent(SomeType, "", "\t")
    ioutil.WriteFile("test.json", b, 0644)

}

Why is this useful? File.Write() returns bytes written to the file! So this is perfect if you want to manage memory or storage.

WriteDataToFileAsJSON() (numberOfBytesWritten, error)
like image 33
accnameowl Avatar answered Sep 28 '22 01:09

accnameowl