如何更改从Go服务器返回数据而不保存数据的格式

时间:2019-08-05 05:56:50

标签: json go

我正在对我从通道获取的每个搜索结果进行编码,然后将其发送到响应编写器,然后刷新它,但是发送的数据如下:

[{..}]
[{..}]
[{..}]

这是具有单个值的多个数组

但是我要求发送数据的格式就像 [{..},{..},{..}]是具有多个值的单个数组。

如果我之前将数据存储在变量中,然后对整个数据进行编码,则可以完成此操作,但是如果我将其存储,我的运行时间将耗尽内存。

有什么方法可以将其转换为所需的格式而无需存储它,或者如何解决我的内存问题。

我正在4GB ram sles12 sp3系统中运行我的Go服务器

ch := make(chan *ldap.SearchResult)
//result := &ldap.SearchResult{}

flusher, ok := w.(http.Flusher)

if !ok {
    http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
    return
}

wg := sync.WaitGroup{}
wg.Add(1)

go func() {
    for res := range ch {
        resp := SearchResultToObjectType(res)

        json.NewEncoder(w).Encode(resp)

        flusher.Flush()
        //result.Entries = append(result.Entries, res.Entries...)
        //result.Controls = append(result.Controls, res.Controls...)
        //result.Referrals = append(result.Referrals, res.Referrals...)
    }
    wg.Done()
}()

err = conn.SearchWithChannel(searchRequest, ch)

wg.Wait()

if err != nil {
    json.NewEncoder(w).Encode(utils.ParseErrorToJson(err))
    event.LogEventError(err, nil)
}

2 个答案:

答案 0 :(得分:2)

假设resp是一个包含单个元素的切片,然后使用以下代码。该代码将slice元素包装在单个JSON数组中。

go func() {
    enc := json.NewEncoder(w)
    sep := []byte("")
    comma := []byte(",")
    w.Write([]byte("[")
    for res := range ch {
        w.Write(sep)
        sep = comma
        resp := SearchResultToObjectType(res)
        enc.Encode(resp[0])
        flusher.Flush()    
    }
    w.Write([]byte("]")
    wg.Done()
}()

答案 1 :(得分:2)

一种选择是使用如下所示的方法手动构造外部JSON数组:

first := true
w.Write([]byte("["))
for res := range ch {
    if not first {
        w.Write([]byte(","))
    }
    first = false
    ...
    json.NewEncoder(w).Encode(resp)
    ...
}
w.Write([]byte("]"))