这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战。
本文讲述的是合并两个 json 文件,既然是两个 JSON文件的合并。其实就是把两个结构相似的 JSON 文件合并成一个文件, 这样会涉及到文件的读写.
基于 OS 的 文件读写
file, _ := os.Open("test.txt") // 读文件
// 写文件
file, _ := os.OpenFile("test2.txt", os.O_RDWR | os.O_APPEND | os.O_CREATE, 0664)
defer file.Close()
data := []byte("hello go\n")
// 写入字节
count, _ := file.Write(data)
文件读
由于 os.File 也是 io.Reader 的实现,我们可以调用 ioutil.ReadAll(io.Reader) 方法,将文件所有字节读取出来,省去了使用字节缓存循环读取的过程。
file, _ := os.Open("test.txt") // 读文件
文件写
通过File句柄完成写入操作曾使用过 os.Open(name string) 方法,这个方法是以只读方式打开文件的,os 包还提供了 os.OpenFile(name string, flag int, perm FileMode) 方法,通过指定额外的 读写方式 和 文件权限 参数,使文件操作变得更为灵活。
其中,flag 有以下几种常用的值:
os.O_CREATE: create if none exists 不存在则创建
os.O_RDONLY: read-only 只读
os.O_WRONLY: write-only 只写
os.O_RDWR: read-write 可读可写
os.O_TRUNC: truncate when opened 文件长度截为0:即清空文件
os.O_APPEND: append 追加新数据到文件
基于 ioutil 文件读写
文件读基于 io/ioutil 实现
func LoadContentFromFile(file string) (string, error) {
content, err := ioutil.ReadFile(file)
if err != nil {
return "", err
}
return string(content), nil
}
有时候便于分析处理,经常进行一行一行读取
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
file, _ := os.Open("test.txt")
defer file.Close()
// 接受io.Reader类型参数 返回一个bufio.Scanner实例
scanner := bufio.NewScanner(file)
var count int
for scanner.Scan() {
count++
// 读取当前行内容
line := scanner.Text()
fmt.Printf("%d %s\n", count, line)
}
}
文件写基于 io/ioutil 实现
target := "/../../source/mapping.json"
ioutil.WriteFile(str+target,buff.Bytes(),fs.ModeAppend)
json 代码合并
两个 map 进行代码合并
原理很简单,就是进行两个 map 的遍历,然后合并成一个 map
其实是遍历两个 map 然后相同 key 进行合并即可
value := map[string]interface{}{}
for k1, v1 := range sourceInfo1 {
v2, _ := sourceInfo2[k1]
switch v2.(type) {
case map[string]interface{}:
mp1 := v1.(map[string]interface{})
mp2 := v2.(map[string]interface{})
for k3, v3 := range mp1 {
if _, OK := mp2[k3]; !OK {
mp2[k3] = v3
}
}
value[k1] = mp2
case []interface{}:
list1 := v1.([]interface{})
list2 := v2.([]interface{})
list2 = append(list2, list1...)
value[k1] = list2
}
}
查看完整代码
package jsontool
import (
"bytes"
"encoding/json"
"io/fs"
"io/ioutil"
"os"
"strings"
"testing"
"code.byted.org/gopkg/pkg/log"
)
func LoadContentFromFile(file string) (string, error) {
content, err := ioutil.ReadFile(file)
if err != nil {
return "", err
}
return string(content), nil
}
func LoadJsonFromFile(file string) (map[string]interface{}, error) {
content, err := LoadContentFromFile(file)
if err != nil {
return nil, err
}
resultMap := make(map[string]interface{})
err = json.Unmarshal([]byte(content), &resultMap)
if err != nil {
return nil, err
}
return resultMap, nil
}
func TestSetMapping(t *testing.T) {
str, _ := os.Getwd()
sourceInfo1, err1 := LoadJsonFromFile(str + "/../../source/map_1.json")
sourceInfo2, err2 := LoadJsonFromFile(str + "/../../source/map_2.json")
if err1 != nil || err2 != nil {
return
}
value := map[string]interface{}{}
for k1, v1 := range sourceInfo1 {
v2, _ := sourceInfo2[k1]
switch v2.(type) {
case map[string]interface{}:
mp1 := v1.(map[string]interface{})
mp2 := v2.(map[string]interface{})
for k3, v3 := range mp1 {
if _, OK := mp2[k3]; !OK {
mp2[k3] = v3
}
}
value[k1] = mp2
case []interface{}:
list1 := v1.([]interface{})
list2 := v2.([]interface{})
list2 = append(list2, list1...)
value[k1] = list2
}
}
var buff bytes.Buffer
b, _ := json.Marshal(value)
_ = json.Indent(&buff, b, "", " ")
//str, err := PostHeader(buff.String())
//log.Info(util.JsonMarshal(str))
//log.Info(err)
target := "/../../source/mapping.json"
ioutil.WriteFile(str+target,buff.Bytes(),fs.ModeAppend)
log.Info(buff.String())
if strings.Index(str, "\"error_code\":0") >= 0 {
log.Info("set OK")
}
}
看下代码 _ = json.Indent(&buff, b, "", " ") 目的是进行 json 格式化,否则字符串会挤一块
map_1.json 文件:
{
"employees": [
{
"firstName": "Bill",
"lastName": "Gates"
},
{
"firstName": "George",
"lastName": "Bush"
},
{
"firstName": "Thomas",
"lastName": "Carter"
}
]
}
map_2.json 文件
{
"employees": [
{
"firstName": "Bill",
"lastName": "Gates"
},
{
"firstName": "George",
"lastName": "Bush"
},
{
"firstName": "Thomas",
"lastName": "Carter"
}
]
}
生成的文件 mapping.json:
{
"employees": [
{
"firstName": "Bill",
"lastName": "Gates"
},
{
"firstName": "George",
"lastName": "Bush"
},
{
"firstName": "Thomas",
"lastName": "Carter"
},
{
"firstName": "Bill",
"lastName": "Gates"
},
{
"firstName": "George",
"lastName": "Bush"
},
{
"firstName": "Thomas",
"lastName": "Carter"
}
]
}