我需要请求、处理数据并将其格式化为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()
处理不同类型的内存中文件操作问题的一般机制(以及特定于这种情况的机制)是什么?
2条答案
按热度按时间ykejflvf1#
csv.NewWriter
接受一个io.Writer
,因此您可以将http.ResponseWriter
的示例传递给它,而无需将内容写入文件或内存。下面是演示:
e0bqpujr2#
感谢JimB的评论(使用
bytes.Buffer
)以及an answer关于使用指向Buffer
的指针)我设法摆脱了临时文件:更好的答案是Zeke Lu's one。