最近在用阿里云oss select 功能时,发现返回的数据转成string的时候会有部分乱码。但在使用python的sdk的时候就是完全正常的。由于请求头返回的code是206,所以我有点怀疑原因出在这里,而阿里的那个文档(https://help.aliyun.com/document_detail/74054.html?spm=a2c4g.11186623.6.937.S1pqD1) 我是没太看懂。麻烦大神们给看看。
我的关键代码:
```go
func SelectQuery(bucket, objectKey string, config *Config, s *Selector) ([]byte, error) {
content, err := s.toXML()
if err != nil {
return nil, err
}
now := getGmtIso8601(time.Now().Unix())
canonicalizedResource := "/" + bucket + "/" + objectKey + "?x-oss-process=csv/select"
url := fmt.Sprintf("https://%s.oss-cn-hangzhou.aliyuncs.com/%s?x-oss-process=csv/select", bucket, objectKey)
c := &http.Client{
Transport: &http.Transport{
// Proxy: http.ProxyFromEnvironment,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper),
Dial: (&net.Dialer{
Timeout: config.Timeout,
KeepAlive: config.KeepAlive,
}).Dial,
TLSHandshakeTimeout: config.TLSHandshakeTimeout,
ResponseHeaderTimeout: config.ResponseHeaderTimeout,
ExpectContinueTimeout: config.ExpectContinueTimeout,
},
}
req, err := http.NewRequest("POST", url, bytes.NewReader(content))
if err != nil {
return nil, err
}
req.Header.Set("Date", now)
req.Header.Set("Content-Length", strconv.Itoa(len(content)))
//req.Header.Set("Content-MD5", hex.EncodeToString(auth.CalcMD5(content)))
conn := Conn{
Config: config,
Client: c,
}
conn.SignHeader(req, canonicalizedResource)
resp, err := c.Do(req)
fmt.Printf("%+v\n", resp)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return body, errors.New("errors returned from ali oss")
}
return body, nil
}
```
打印信息:
```shell
▶ go run demo.go
&{Status:206 Partial Content StatusCode:206 Proto:HTTP/1.1 ProtoMajor:1 ProtoMinor:1 Header:map[Accept-Ranges:[bytes] Connection:[keep-alive] X-Oss-Storage-Class:[Standard] X-Oss-Server-Time:[60] Date:[Tue, 24 Jul 2018 05:29:38 GMT] Etag:["B9B8FE775557E10E35418410499775CF"] Server:[AliyunOSS] Content-Md5:[ubj+d1VX4Q41QYQQSZd1zw==] Last-Modified:[Mon, 23 Jul 2018 11:22:04 GMT] X-Oss-Object-Type:[Normal] X-Oss-Hash-Crc64ecma:[8407954770141203098] Content-Type:[text/csv] X-Oss-Request-Id:[5B56B942D1B3FA9711693E4D]] Body:0xc420198640 ContentLength:-1 TransferEncoding:[chunked] Close:false Uncompressed:false Trailer:map[] Request:0xc420128000 TLS:0xc4201da000}
���y�176267,0102797,30840
176269,6209470,439050
176271,2028550,111109
176273,0303758,67758
176275,0008536,227506
��176279,6980792,461257
����
```
在文档中,关于返回的数据,是这么说的:
> 返回结果 请求结果以一个个Frame形式返回。每个Frame的格式如下,其中checksum均为CRC32: Frame-Type | Payload Length | Header Checksum | Payload | Payload Checksum <---4 bytes--><---4 bytes----------><-------4 bytes-------><----4bytes----------> 一共有三种不同的Frame Type, 列举如下:
而python的输出如下:
```shell
176267,0102797,30840
176269,6209470,439050
176271,2028550,111109
176273,0303758,67758
176275,0008536,227506
176279,6980792,461257
```
有疑问加站长微信联系(非本文作者)