Экспорт JSON в один файл из функции цикла
Я написал код, который обращается к одному общедоступному API и сохраняет вывод JSON в файл. Но данные хранятся в файле построчно, а не в одном формате JSON.
Например.
Текущий выход:
{"ip":"1.1.1.1", "Country":"US"}
{"ip":"8.8.8.8", "Country":"IN"}
Желаемый результат:
[
{"ip":"1.1.1.1", "Country":"US"},
{"ip":"8.8.8.8", "Country":"IN"}
]
Я знаю, что это должно быть довольно просто, и я что-то упускаю.
Мой текущий код:
Читать IP из файла и обращаться к API по одному на каждом IP.
func readIPfromFile(filename string, outFile string, timeout int) {
data := jsonIn{}
//open input file
jsonFile, err := os.Open(filename) //open input file
...
...
jsonData := bufio.NewScanner(jsonFile)
for jsonData.Scan() {
// marshal json data & check for logs
if err := json.Unmarshal(jsonData.Bytes(), &data); err != nil {
log.Fatal(err)
}
//save to file
url := fmt.Sprintf("http://ipinfo.io/%s", data.Host)
GetGeoIP(url, outFile, timeout)
}
}
Сделать HTTP-запрос с настраиваемым заголовком запроса и вызвать функцию записи в файл.
func GetGeoIP(url string, outFile string, timeout int) {
geoClient := http.Client{
Timeout: time.Second * time.Duration(timeout), // Timeout after 5 seconds
}
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("accept", "application/json")
res, getErr := geoClient.Do(req)
if getErr != nil {
log.Fatal(getErr)
}
if res.Body != nil {
defer res.Body.Close()
}
body, readErr := ioutil.ReadAll(res.Body)
if readErr != nil {
log.Fatal(readErr)
}
jsonout := jsonOut{}
jsonErr := json.Unmarshal(body, &jsonout)
if jsonErr != nil {
log.Fatal(jsonErr)
}
file, _ := json.Marshal(jsonout)
write2file(outFile, file)
}
Чтобы записать данные в файл:
func write2file(outFile string, file []byte) {
f, err := os.OpenFile(outFile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
log.Fatal(err)
}
defer f.Close()
if _, err = f.WriteString(string(file)); err != nil {
log.Fatal(err)
}
if _, err = f.WriteString("\n"); err != nil {
log.Fatal(err)
}
Я знаю, я могу редактировать
f.WriteString("\n");
к
f.WriteString(",");
добавить запятую, но по-прежнему добавлять [] в файл для меня сложно.
1 ответ
Во-первых, пожалуйста, не изобретайте новый способ маршалинга json, просто используйте встроенный в golang
encoding/json
или другая библиотека на github.
Во-вторых, если вы хотите создать строку json, представляющую массив объектов, вам нужно создать массив объектов в golang и маршалировать его в строку (или, точнее, в массив байтов)
Я создаю простой, как показано ниже, но, пожалуйста, сделай сам, если это возможно.