Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimanakah saya boleh menulis ke fail dalam ingatan dan kemudian menghantarnya melalui HTTP tanpa menggunakan fail perantaraan?

Bagaimanakah saya boleh menulis ke fail dalam ingatan dan kemudian menghantarnya melalui HTTP tanpa menggunakan fail perantaraan?

王林
王林ke hadapan
2024-02-06 11:00:04951semak imbas

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

Kandungan soalan

Saya perlu meminta, memproses dan memformat data ke dalam csv dan kemudian menghantarnya melalui perkhidmatan web atas permintaan.

Dengan mengandaikan data yang diminta dan diproses berada dalam data di bawah, saya berjaya melakukan ini menggunakan fail sementara perantaraan:

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)
}

Permintaan berjaya:

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

Setakat ini bagus - sekarang saya mahu memadamkan fail perantaraan melalui

  • Gunakan "bekas" memori untuk menulis data csv
  • Tulis kandungannya sebagai bait kepada penulis http

Saya masih tidak begitu faham cara menggunakan io.*bufio.* untuk log masuk jenis yang diperlukan:

  • csv.newwriter() 需要 *os.file 并返回 *csv.writer
  • Ini *csv.writer 内容需要以某种方式提取为 byte ...
  • ...Untuk menyediakan http.responsewriter.write()

Apakah mekanisme umum (dan yang khusus untuk kes ini) untuk menyelesaikan pelbagai jenis masalah manipulasi fail memori?


Jawapan Betul


csv.newwriter 采用 io.writer,因此您可以将 http.responsewriter dihantar kepadanya tanpa menulis kandungan ke fail atau memori.

Ini demonya:

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)
}

Atas ialah kandungan terperinci Bagaimanakah saya boleh menulis ke fail dalam ingatan dan kemudian menghantarnya melalui HTTP tanpa menggunakan fail perantaraan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam