Uzyskaj dostęp do odpowiedzi HTTP jako ciąg w Go

123

Chciałbym przeanalizować odpowiedź żądania internetowego, ale mam problem z dostępem do niej jako ciągu.

func main() {
    resp, err := http.Get("http://google.hu/")
    if err != nil {
        // handle error
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)

    ioutil.WriteFile("dump", body, 0600)

    for i:= 0; i < len(body); i++ {
        fmt.Println( body[i] ) // This logs uint8 and prints numbers
    }

    fmt.Println( reflect.TypeOf(body) )
    fmt.Println("done")
}

Jak mogę uzyskać dostęp do odpowiedzi w postaci ciągu? ioutil.WriteFilezapisuje poprawnie odpowiedź do pliku.

Sprawdziłem już numer referencyjny pakietu, ale nie jest to zbyt pomocne.

Tibor Szasz
źródło

Odpowiedzi:

221

bs := string(body) powinno wystarczyć, aby dać ci ciąg.

Stamtąd możesz użyć go jako zwykłego ciągu.

Trochę jak w tym wątku :

var client http.Client
resp, err := client.Get(url)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

if resp.StatusCode == http.StatusOK {
    bodyBytes, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }
    bodyString := string(bodyBytes)
    log.Info(bodyString)
}

Zobacz także GoByExample .

Dalej należy zauważyć, poniżej (oraz w ZZN „s odpowiedź ), to konwersja (patrz specyfikacja ).
Zobacz „ Ile to kosztuje []byte(string)? ” (Odwrotny problem, ale obowiązuje ten sam wniosek), gdzie zzzz wspomniał:

Niektóre konwersje są takie same jak rzutowanie, na przykład uint(myIntvar), które po prostu reinterpretuje bity w miejscu.

Sonia dodaje:

Tworzenie łańcucha z kawałka bajtu zdecydowanie obejmuje przydzielenie ciągu na stercie. Wymusza to własność niezmienności.
Czasami możesz zoptymalizować, wykonując jak najwięcej pracy z bajtem [], a następnie tworząc na końcu łańcuch. bytes.BufferTyp jest często użyteczne.

VonC
źródło
Dzięki. Czy masz jakieś sugestie, jak mogłem sam to rozgryźć? Jak to robi string ()? Dlaczego nie mogę tego zobaczyć z Reflect.TypeOf?
Tibor Szasz
1
@TiborSzasz To prosta konwersja: patrz blog.golang.org/slices#TOC_12 .
VonC
Niewielkim ulepszeniem twojego kodu byłoby użycie http.StatusOKzamiast surowej 200wartości!
Shadoninja
Robiłem to i stwierdziłem, że moje ciała żądań zawsze mają na końcu znak nowej linii. Czy jest to normalne w przypadku treści żądania, czy jest to spowodowane ioutil.ReadAll()??
sixty4bit
29

Metoda, której używasz do odczytywania odpowiedzi treści http, zwraca fragment bajtu:

func ReadAll(r io.Reader) ([]byte, error)

oficjalna dokumentacja

Możesz przekonwertować []bytena ciąg przy użyciu

body, err := ioutil.ReadAll(resp.Body)
bodyString := string(body)
tsabsch
źródło
1

string (byteslice) przekonwertuje kawałek bajtu na łańcuch, po prostu wiedz, że jest to nie tylko zwykła konwersja typów, ale także kopiowanie pamięci.

zzn
źródło