猿问

在服务器上加载 CSV 数据,将数据转换为 JSON 并使用 Golang 使用 Json

我正在尝试构建一个 TCP 服务器,它从CSV文件加载数据集并提供一个接口来查询数据集。TCP 服务器将暴露 4040 端口。 CSV 文件包含与冠状病毒病例相关的以下列:

  • 累积测试阳性

  • 进行的累积测试

  • 日期

  • 出院

  • 已到期

  • 录取

  • 区域用户应该能够在基于 Linux/Unix 的系统上使用NetCat命令连接到服务器。 nc localhost 4040

一旦连接到 TCP,用户应该能够通过发送 JSON 格式的查询与应用程序进行通信。

{

    "query": {

        "region": "Sindh"

    }

}

{

    "query": {

        "date": "2020-03-20"

    }

}

这会正确加载 csv 并将其转换为 JSON。但是,当我尝试使用 NetCat 命令运行查询时,它返回空 JSON 元素。请指导我哪里出错了。



饮歌长啸
浏览 179回答 2
2回答

翻过高山走不出你

猜你想要这个:╭─root@DESKTOP-OCDRD7Q ~╰─# nc localhost 4040{"get": "Sindh"}[{"Covid_Positive":"1","Coivd_Performed":"1","Covid_Date":"1","Covid_Discharged":"1","Covid_Expired":"1","Covid_Region":"Sindh","Covid_Admitted":"1"}]您应该做的只是修改您的 json 请求。package mainimport (    "bufio"    "encoding/csv"    "encoding/json"    "flag"    "fmt"    "io"    "log"    "net"    "os")type CovidPatient struct {    Positive   string `json:"Covid_Positive"`    Performed  string `json:"Coivd_Performed"`    Date       string `json:"Covid_Date"`    Discharged string `json:"Covid_Discharged"`    Expired    string `json:"Covid_Expired"`    Region     string `json:"Covid_Region"`    Admitted   string `json:"Covid_Admitted"`}type DataRequest struct {    Get CovidPatient `json:"get"`}type DataError struct {    Error string `json:"Covid_error"`}func Load(path string) []CovidPatient {    table := make([]CovidPatient, 0)    var patient CovidPatient    file, err := os.Open(path)    if err != nil {        panic(err.Error())    }    defer file.Close()    reader := csv.NewReader(file)    csvData, err := reader.ReadAll()    if err != nil {        fmt.Println(err)        os.Exit(1)    }    for _, row := range csvData {        patient.Positive = row[0]        patient.Performed = row[1]        patient.Date = row[2]        patient.Discharged = row[3]        patient.Expired = row[4]        patient.Region = row[5]        patient.Admitted = row[6]        table = append(table, patient)    }    return table}func Find(table []CovidPatient, filter CovidPatient) []CovidPatient {    result := make([]CovidPatient, 0)    log.Println(filter, table)    for _, cp := range table {        if filter.Positive == "" {        } else if filter.Positive != cp.Positive {            continue        }        if filter.Performed == "" {        } else if filter.Performed != cp.Performed {            continue        }        if filter.Date == "" {        } else if filter.Date != cp.Date {            continue        }        if filter.Discharged == "" {        } else if filter.Discharged != cp.Discharged {            continue        }        if filter.Expired == "" {        } else if filter.Expired != cp.Expired {            continue        }        if filter.Region == "" {        } else if filter.Region != cp.Region {            continue        }        if filter.Admitted == "" {        } else if filter.Admitted != cp.Admitted {            continue        }        result = append(result, cp)    }    return result}var (    patientsDetail = Load("./covid_final_data.csv"))func main() {    log.SetFlags(log.Lshortfile | log.Ltime)    var addr string    var network string    flag.StringVar(&addr, "e", ":4040", "service endpoint [ip addr or socket path]")    flag.StringVar(&network, "n", "tcp", "network protocol [tcp,unix]")    flag.Parse()    switch network {    case "tcp", "tcp4", "tcp6", "unix":    default:        fmt.Println("unsupported network protocol")        os.Exit(1)    }    ln, err := net.Listen(network, addr)    if err != nil {        log.Println(err)        os.Exit(1)    }    defer ln.Close()    log.Println("Covid19 Condition in Pakistan")    log.Printf("Service started: (%s) %s\n", network, addr)    for {        conn, err := ln.Accept()        if err != nil {            log.Println(err)            conn.Close()            continue        }        log.Println("Connected to ", conn.RemoteAddr())        go handleConnection(conn)    }}func handleConnection(conn net.Conn) {    defer func() {        if err := conn.Close(); err != nil {            log.Println("error closing connection:", err)        }    }()    reader := bufio.NewReaderSize(conn, 100)    for {        buf, err := reader.ReadBytes('|')        if err != nil {            if err != io.EOF {                log.Println("connection read error:", err)                return            }        }        reader.Reset(conn)        var req DataRequest        if err := json.Unmarshal(buf[:len(buf)-1], &req); err != nil {            log.Println("failed to unmarshal request:", string(buf), err)            cerr, jerr := json.Marshal(DataError{Error: err.Error()})            if jerr != nil {                log.Println("failed to marshal DataError:", jerr)                continue            }            if _, werr := conn.Write(cerr); werr != nil {                log.Println("failed to write to DataError:", werr)                return            }            continue        }        result := Find(patientsDetail, req.Get)        rsp, err := json.Marshal(&result)        if err != nil {            log.Println("failed to marshal data:", err)            if _, err := fmt.Fprintf(conn, `{"data_error":"internal error"}`); err != nil {                log.Printf("failed to write to client: %v", err)                return            }            continue        }        if _, err := conn.Write(rsp); err != nil {            log.Println("failed to write response:", err)            return        }    }}查询是:╭─root@DESKTOP-OCDRD7Q ~╰─# nc localhost 4040                                                                                             127 ↵{    "get": {        "Covid_Region": "Sindh",        "Covid_Date": "2020-03-20"    }}|[{"Covid_Positive":"1","Coivd_Performed":"1","Covid_Date":"2020-03-20","Covid_Discharged":"1","Covid_Expired":"1","Covid_Region":"Sindh","Covid_Admitted":"1"}]

回首忆惘然

在 functionhandleConnection中,第一件事是“读取直到找到第一个}”,假设用户正在发送请求:{ "get": { "Covid_Region": "Sindh", "Covid_Date": "2020-03-20" } }然后该步骤如下:{ "get": { "Covid_Region": "Sindh", "Covid_Date": "2020-03-20" }}请注意缺少尾随,然后json.Unmarshal尝试在没有最后一个的情况下解组查询}(这是无效的 json)。这个问题可以利用 JSON 流解码,换句话说,使用json.NewDecoder(r io.Reader)代替json.Unmarshal. 让我复制并修改该函数的第一部分:func handleConnection(conn net.Conn) {    defer func() {        if err := conn.Close(); err != nil {            log.Println("error closing connection:", err)        }    }()    jsonDecoder := json.NewDecoder(conn) // A json decoder read a stream to find a                                         // valid JSON and stop just the byte                                         // after the JSON ends. Process can be                                         // repeated.    for {        var req DataRequest        err := jsonDecoder.Decode(&req)        if err == io.EOF {            log.Println("finish")            return        }        if err != nil {            log.Println("unmarshal:", err)            return        }        result := Find(patientsDetail, req.Get) // Here query the system        // ... 可能现在它可以工作了,但是您也可以利用 json 流通过jsonEncoder := json.NewEncoder(conn)before de for 循环发送回响应,并像这样发送请求:        err := jsonEncoder.Encode(&result)        if err != nil {            log.Println("failed to marshal data:", err)            // ...            continue        }
随时随地看视频慕课网APP

相关分类

Go
我要回答