我需要请求、处理数据并将其格式化为 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)
}