dtysql0586 2019-02-25 13:23
浏览 48
已采纳

更改文件的最后一个字符

I want to continuously write json objects to a file. To be able to read it, I need to wrap them into an array. I don't want to read the whole file, for simple appending. So what I' doing now:

comma := []byte(", ")
    file, err := os.OpenFile(erp.TransactionsPath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
    if err != nil {
        return err
    }
    transaction, err := json.Marshal(t)
    if err != nil {
        return err
    }
    transaction = append(transaction, comma...)
    file.Write(transaction)

But with this implementation I will need to add []scopes by hand(or via some script) before reading. How can I add an object before closing scope on each writing?

  • 写回答

1条回答 默认 最新

  • doudeng9425 2019-02-25 13:36
    关注

    You don't need to wrap the JSON objects into an array, you can just write them as-is. You may use json.Encoder to write them to the file, and you may use json.Decoder to read them. Encoder.Encode() and Decoder.Decode() encode and decode individual JSON values from a stream.

    To prove it works, see this simple example:

    const src = `{"id":"1"}{"id":"2"}{"id":"3"}`
    dec := json.NewDecoder(strings.NewReader(src))
    
    for {
        var m map[string]interface{}
        if err := dec.Decode(&m); err != nil {
            if err == io.EOF {
                break
            }
            panic(err)
        }
        fmt.Println("Read:", m)
    }
    

    It outputs (try it on the Go Playground):

    Read: map[id:1]
    Read: map[id:2]
    Read: map[id:3]
    

    When writing to / reading from a file, pass the os.File to json.NewEncoder() and json.NewDecoder().

    Here's a complete demo which creates a temporary file, uses json.Encoder to write JSON objects into it, then reads them back with json.Decoder:

    objs := []map[string]interface{}{
        map[string]interface{}{"id": "1"},
        map[string]interface{}{"id": "2"},
        map[string]interface{}{"id": "3"},
    }
    
    file, err := ioutil.TempFile("", "test.json")
    if err != nil {
        panic(err)
    }
    
    // Writing to file:
    enc := json.NewEncoder(file)
    for _, obj := range objs {
        if err := enc.Encode(obj); err != nil {
            panic(err)
        }
    }
    
    // Debug: print file's content
    fmt.Println("File content:")
    if data, err := ioutil.ReadFile(file.Name()); err != nil {
        panic(err)
    } else {
        fmt.Println(string(data))
    }
    
    // Reading from file:
    if _, err := file.Seek(0, io.SeekStart); err != nil {
        panic(err)
    }
    dec := json.NewDecoder(file)
    for {
        var obj map[string]interface{}
        if err := dec.Decode(&obj); err != nil {
            if err == io.EOF {
                break
            }
            panic(err)
        }
        fmt.Println("Read:", obj)
    }
    

    It outputs (try it on the Go Playground):

    File content:
    {"id":"1"}
    {"id":"2"}
    {"id":"3"}
    
    Read: map[id:1]
    Read: map[id:2]
    Read: map[id:3]
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 comsol稳态求解器 找不到解,奇异矩阵有1个空方程返回的解不收敛。没有返回所有参数步长;pid控制
  • ¥15 怎么让wx群机器人发送音乐
  • ¥15 fesafe材料库问题
  • ¥35 beats蓝牙耳机怎么查看日志
  • ¥15 Fluent齿轮搅油
  • ¥15 八爪鱼爬数据为什么自己停了
  • ¥15 交替优化波束形成和ris反射角使保密速率最大化
  • ¥15 树莓派与pix飞控通信
  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功