最新公告
  • 欢迎您光临码农资源网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!加入我们
  • 如何写入内存中的文件,然后通过 HTTP 发送它而不使用中间文件?

    如何写入内存中的文件,然后通过 http 发送它而不使用中间文件?

    问题内容

    我需要请求、处理数据并将其格式化为 csv,然后根据请求通过 web 服务发送它们。

    假设请求和处理的数据位于下面的 data 中,我设法使用中间临时文件来做到这一点:

    package main
    
    import (
        "encoding/csv"
        "io/ioutil"
        "net/http"
        "os"
        "strconv"
    
        "github.com/go-chi/chi/v5"
    )
    
    type data struct {
        name string
        age  int
    }
    
    func main() {
        data := []data{
            {"john", 30},
            {"jane", 20},
        }
        tempfilename := "temp.csv"
        // create temporary intermediate file
        file, err := os.create(tempfilename)
        defer file.close()
        if err != nil {
            panic(err)
        }
        w := csv.newwriter(file)
        var csvdata [][]string
        for _, record := range data {
            row := []string{record.name, strconv.itoa(record.age)}
            csvdata = append(csvdata, row)
        }
        w.writeall(csvdata)
    
        // read temporary intermediate file to send it via http
        filebytes, err := ioutil.readfile(tempfilename)
        if err != nil {
            panic(err)
        }
        // send the file on request
        router := chi.newrouter()
        router.get("/data", func(w http.responsewriter, r *http.request) {
            w.header().set("content-type", "application/octet-stream")
            w.writeheader(http.statusok)
            w.write(filebytes)
        })
        http.listenandserve(":8087", router)
    }
    

    请求成功:

    PS C:temp> wget http://localhost:8087/data
    --2023-06-13 15:34:00--  http://localhost:8087/data
    Resolving localhost (localhost)... ::1, 127.0.0.1
    Connecting to localhost (localhost)|::1|:8087... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 16 [application/octet-stream]
    Saving to: 'data'
    
    data                          100%[=================================================>]      16  --.-KB/s    in 0s
    
    2023-06-13 15:34:00 (523 KB/s) - 'data' saved [16/16]
    
    PS C:temp> cat data
    John,30
    Jane,20

    到目前为止一切顺利 – 现在我想通过

    删除中间文件

    • 使用内存“容器”来写入 csv 数据
    • 将其内容以字节形式写入 http 编写器

    我还是不太明白如何使用io.*bufio.*来登陆所需的类型:

    • csv.newwriter() 需要 *os.file 并返回 *csv.writer
    • 这个 *csv.writer 内容需要以某种方式提取为 byte
    • …为了提供 http.responsewriter.write()

    解决不同类型的内存文件操作问题的一般机制(以及特定于本例的机制)是什么?

    正确答案

    csv.newwriter 采用 io.writer,因此您可以将 http.responsewriter 的实例传递给它,而无需将内容写入文件或内存。

    这是演示:

    package main
    
    import (
        "encoding/csv"
        "fmt"
        "net/http"
        "strconv"
    
        "github.com/go-chi/chi/v5"
    )
    
    type Data struct {
        Name string
        Age  int
    }
    
    func main() {
        router := chi.NewRouter()
        router.Get("/data", func(w http.ResponseWriter, r *http.Request) {
            w.Header().Set("Content-Type", "application/octet-stream")
            w.WriteHeader(http.StatusOK)
            data := []Data{
                {"John", 30},
                {"Jane", 20},
            }
            csvWriter := csv.NewWriter(w)
            var csvData [][]string
            for _, record := range data {
                row := []string{record.Name, strconv.Itoa(record.Age)}
                csvData = append(csvData, row)
            }
            if err := csvWriter.WriteAll(csvData); err != nil {
                // handle the error
                fmt.Println(err)
            }
        })
        http.ListenAndServe(":8087", router)
    }
    
    想要了解更多内容,请持续关注码农资源网,一起探索发现编程世界的无限可能!
    本站部分资源来源于网络,仅限用于学习和研究目的,请勿用于其他用途。
    如有侵权请发送邮件至1943759704@qq.com删除

    码农资源网 » 如何写入内存中的文件,然后通过 HTTP 发送它而不使用中间文件?
    • 7会员总数(位)
    • 25846资源总数(个)
    • 0本周发布(个)
    • 0 今日发布(个)
    • 293稳定运行(天)

    提供最优质的资源集合

    立即查看 了解详情