Как прочитать содержимое файла из ответа http.Request - PullRequest
0 голосов
/ 30 сентября 2019

Я использую приведенный ниже код для отправки запроса на http-сервер.

Сервер отправляет ответ, содержащий эти заголовки http

Content-Disposition:[attachment;filename=somefilename.csv] 
Content-Type:[text/csv; charset=UTF-8]

Как мне перейти к получению содержимогофайл с ответом?

baseUrl := "Some url that i call to fetch csv file"

client := http.Client{}

resp, _ := client.Get(baseUrl)
defer resp.Body.Close()

fmt.Println(resp)

// &{200 OK 200 HTTP/2.0 2 0 map[Content-Disposition:[attachment;filename=somefilename.csv] Content-Type:[text/csv; charset=UTF-8] Date:[Mon, 30 Sep 2019 09:54:08 GMT] Server:[Jetty(9.2.z-SNAPSHOT)] Vary:[Accept]] {0xc000530280} -1 [] false false map[] 0xc000156200 0xc0000c26e0}

Ответы [ 2 ]

2 голосов
/ 30 сентября 2019

Вы должны использовать тело запроса.

baseUrl := "Some url that i call to fetch csv file"

client := http.Client{}

resp, _ := client.Get(baseUrl)
defer resp.Body.Close()
io.Copy(os.Stdout, resp.Body) // this line.

fmt.Println(resp)

, если вам приходится иметь дело с данными многочастной формы https://golang.org/pkg/net/http/#Request.FormFile

Учитывая следующий комментарий,

Теперь я вижу после печати, соответственно, что есть текст в формате csv, но введите http.Response Мне нужно разобраться с golang.org/pkg/encoding/csv/#Reader, как включить или отключить строку, чтобы иметь возможностьчитатель, чтобы прочитать его, или я что-то пропустил?

OP должен понимать, что тело ответа http реализует интерфейс io.Reader. Когда HTTP-ответ возвращается с сервера, тело не считывается непосредственно в память, так как фрагмент байтов []byte.

OP должен также отметить, что csv.Reader является реализацией для декодирования CSV-кодированного содержимого. который потребляет io.Reader. Под капотом он не хранит все содержимое файла в памяти, он читает то, что необходимо для декодирования одной строки и продолжения.

Вследствие этих двух важных свойств реализации Голанга, этопросто и естественно подключить считыватель тела ответа к считывателю csv.

На вопрос, что такое io.Reader, OP должен выяснить, что он способен читать поток байтов кусками max lenп. Это иллюстрируется сигнатурой уникального метода этого интерфейса Read([]byte) (int, error)

Этот интерфейс разработан таким образом, что он минимизирует потребляемую память и выделения.

ref links

Все, что сказано, окончательный код написан тривиально,

package main

import (
    "encoding/csv"
    "fmt"
    "io"
    "log"
    "net/http"
)

func main() {
    baseUrl := "https://geolite.maxmind.com/download/geoip/misc/region_codes.csv"

    client := http.Client{}

    resp, err := client.Get(baseUrl)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
    fmt.Println(resp)

    r := csv.NewReader(resp.Body)

    for {
        record, err := r.Read()
        if err == io.EOF {
            break
        }
        if err != nil {
            log.Fatal(err)
        }

        fmt.Println(record)
    }
}
1 голос
/ 30 сентября 2019

Самый простой способ - использовать метод ioutil.ReadAll для чтения всего тела. В теле реализован интерфейс io.Reader, поэтому все, что вы можете сделать с помощью ридера, можно сделать с помощью тела. Это включает в себя передачу его на стандартный вывод, как показал mh-cbon в своем ответе.

baseUrl := "Some url that i call to fetch csv file"

resp, err := http.Get(baseUrl)
if err != nil {
    // do something with the error
}
defer resp.Body.Close()

content, err := ioutil.ReadAll(resp.Body)
if err != nil {
    // do something with the error
}

fmt.Println(string(content))

Обратите внимание, что я удалил client. Он не нужен для простых GET звонков. Если вам нужно больше настроек, используйте http.Client, как вы делали в вашем примере.

Также обратите внимание, что content имеет тип []byte, но его можно легко преобразовать в строку, как указано выше в операторе печати. .

...