```go
package main
import(
"fmt"
"net/http"
"compress/gzip"
)
func main() {
url := "https://blog.csdn.net/yjp19871013/article/details/82555417"
client := &http.Client {};
req, err := http.NewRequest("GET", url, nil);
if (nil != err) {
return;
}
req.Header.Add("Accept-Encoding", "gzip, deflate");
resp, err := client.Do(req)
if (nil != err) {
return;
}
defer resp.Body.Close();
if 200 == resp.StatusCode {
a := resp.Header
for k,
v := range a {
fmt.Println(k, v)
}
fmt.Println(resp.Header.Get("Content-Encoding"));
reader, _ := gzip.NewReader(resp.Body)
for {
buf := make([] byte, 1024)
n,err := reader.Read(buf)
if nil != err {
return;
}
if 0 == n {
return ;
}
fmt.Println(string(buf))
}
} else {
fmt.Println(resp.StatusCode)
}
}
```
我尝试研究了一下源码
```go
// Reader is the interface that wraps the basic Read method.
//
// Read reads up to len(p) bytes into p. It returns the number of bytes
// read (0 <= n <= len(p)) and any error encountered. Even if Read
// returns n < len(p), it may use all of p as scratch space during the call.
// If some data is available but not len(p) bytes, Read conventionally
// returns what is available instead of waiting for more.
//
// When Read encounters an error or end-of-file condition after
// successfully reading n > 0 bytes, it returns the number of
// bytes read. It may return the (non-nil) error from the same call
// or return the error (and n == 0) from a subsequent call.
// An instance of this general case is that a Reader returning
// a non-zero number of bytes at the end of the input stream may
// return either err == EOF or err == nil. The next Read should
// return 0, EOF.
//
// Callers should always process the n > 0 bytes returned before
// considering the error err. Doing so correctly handles I/O errors
// that happen after reading some bytes and also both of the
// allowed EOF behaviors.
//
// Implementations of Read are discouraged from returning a
// zero byte count with a nil error, except when len(p) == 0.
// Callers should treat a return of 0 and nil as indicating that
// nothing happened; in particular it does not indicate EOF.
//
// Implementations must not retain p.
type Reader interface {
Read(p []byte) (n int, err error)
}
```
也就是说你应该在判断err之前处理部分数据,这才符合人家规定。而且我看你的错误是一个确定的返回
也可以用下面这个逻辑不处理那种错误,网上有其他人遇到解决方案也是遇到这个错误忽略就好
```go
byt, err := ioutil.ReadAll(reader)
if err != nil && err != io.ErrUnexpectedEOF {
fmt.Println("ioutil.ReadAll", err)
return
}
```
遇到错误不能一棒子打死,得分析这是正常错误还是需要处理的错误。
#6
更多评论
io.Reader接口说明里面讲的很清楚,Read会返回n>0且err=EOF的情况,即读取最后不满buffer长度的数据场景,修改成如下即可。
```go
for {
buf := make([] byte, 1024)
n,err := reader.Read(buf)
if n > 0 {
fmt.Println(string(buf))
}
if nil != err {
return;
}
}
```
#1
看来楼主有些写法还在用C语言的习惯啊。不过从io.Reader里面读出全部数据还是建议使用byt, err := ioutil.ReadAll(reader)
如果坚持自己写方法的话可以参考一楼回答。我对楼主的代码做了写更改,就是把一些写法简化,去掉分号。
```go
package main
import (
"compress/gzip"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
url := "https://blog.csdn.net/yjp19871013/article/details/82555417"
client := &http.Client{}
req, err := http.NewRequest("GET", url, nil)
if nil != err {
return
}
req.Header.Add("Accept-Encoding", "gzip, deflate")
resp, err := client.Do(req)
if nil != err {
return
}
defer resp.Body.Close()
if 200 == resp.StatusCode {
a := resp.Header
for k, v := range a {
fmt.Println(k, v)
}
fmt.Println(resp.Header.Get("Content-Encoding"))
reader, err := gzip.NewReader(resp.Body)
if nil != err {
return
}
byt, err := ioutil.ReadAll(reader)
if nil != err {
return
}
fmt.Println(string(byt))
} else {
fmt.Println(resp.StatusCode)
}
}
```
#2