Записать Struct в файл Json с помощью полей структуры (не ключей json)

Как я могу прочитать json файл в struct, а затем Marshal обратно в строку json с полями Struct как ключи (а не оригинальные json-ключи)?

(см. ниже Desired Output to Json File...)

код:

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)
}

Вывод на экран:

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

Выход в файл Json:

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

Желаемый вывод в файл Json:

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

Ответ 1

Если я правильно понял ваш вопрос, все, что вы хотите сделать, это удалить теги json из вашего определения структуры.

Итак:

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)
}

Результаты в:

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

И вывод файла:

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

Пример выполнения http://play.golang.org/p/dC3s37HxvZ

Примечание. GetCount показывает 0, так как он был прочитан как "get_count". Если вы хотите читать в JSON, который имеет "get_count" vs. "GetCount", но выводит "GetCount", вам нужно будет провести дополнительный синтаксический анализ.

См. Go- Скопируйте все общие поля между структурами для получения дополнительной информации об этой конкретной ситуации.

Ответ 2

Попробуйте изменить формат json в структуре

type Rankings struct {
    Keyword  string `json:"Keyword"`
    GetCount uint32 `json:"Get_count"`
    Engine   string `json:"Engine"`
    Locale   string `json:"Locale"`
    Mobile   bool   `json:"Mobile"`
}

Ответ 3

Акусация произошла благодаря использованию json.Marshal()/json.MarshalIndent(). Он перезаписывает существующий файл, который в моем случае был неоптимальным. Я просто хотел добавить контент в текущий файл и сохранить старый контент.

Это записывает данные через буфер с типом bytes.Buffer.

Это то, что я собрал до сих пор:

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
}

Это выполнение функции вместе со стандартным json.Marshal() или json.MarshalIndent(), который перезаписывает файл.

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)

}

Почему это полезно? File.Write() возвращает байты, записанные в файл! Так что это идеально, если вы хотите управлять памятью или хранилищем.

WriteDataToFileAsJSON() (numberOfBytesWritten, error)