Go 合并两个文件

1,929 阅读3分钟

这是我参与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"
        }
    ]
}

欢迎关注公众号:程序员财富自由之路