在python SDK 下尝试上传文件到 BCS 时遇到错误,出现提示是 UnicodeDecodeError: 'utf8' codec can't decode byte 0xa7 in position 6: invalid start byte
。又是编码问题,看看折腾过程:
我上传的是图片,因为以前在用官方的代码测试时能正确上传。以下是官方部分重要代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def test_bcs():
### 首先通过云存储管理界面,创建一个bucket
bname = 'test-bucket'
### 创建BCS管理对象
baebcs = bcs.BaeBCS(HOST, AK, SK)
### 读取一个测试文件的内容
filename = os.path.dirname(__file__) + "/testdata"
with open(filename) as fd:
data = fd.read()
### 将文件内容上传到 '/obj1' 下
o1 = '/obj1'
e, d = baebcs.put_object(bname, o1, data)
assert e == 0
既然是编码的问题,那尝试转换一下编码,encode、decode都轮流上马。但还是没用,尝试用其它方式,如StringIO,tmpfile等,还用到PIL 对图像转换一下。还是出现类似下面的提示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Traceback (most recent call last):
File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/site-packages/tornado/web.py", line 954, in _execute
getattr(self, self.request.method.lower())(*args, **kwargs)
File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/site-packages/tornado/web.py", line 1667, in wrapper
return method(self, *args, **kwargs)
File "/home/bae/instanceall/instance1/codefs/bae4py.duapp.com/admin.py", line 126, in post
d = upload(BUCKET, "/upload/%s" % new_file_name, myfile['body'])
File "/home/bae/instanceall/instance1/codefs/bae4py.duapp.com/admin.py", line 91, in upload
e,r = mybcs.put_object(bucketname, savename, filedata)
File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/bae/api/bcs/bcs.py", line 74, in put_object
r = self.httpc.put(url, data, headers={})
File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/bae/api/bcs/httpc.py", line 132, in put
return self.request('PUT', url, body, headers)
File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/bae/api/bcs/httpc.py", line 90, in request
response = self.send_request(verb, url, data, headers)
File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/bae/api/bcs/httpc.py", line 118, in send_request
conn.request(verb, path, data, headers)
File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/httplib.py", line 973, in request
self._send_request(method, url, body, headers)
File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/httplib.py", line 1007, in _send_request
self.endheaders(body)
File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/httplib.py", line 969, in endheaders
self._send_output(message_body)
File "/home/bae/instanceall/instance1/pyruntime/lib/python2.7/httplib.py", line 818, in _send_output
msg += message_body
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa7 in position 6: invalid start byte
尝试上传其它文件,如文本文件,正常!
找到以前测试成功的代码,在线一步一步调试,看哪个地方出问题。
最后怎么着?
把"/upload/" + new_file_name 改为 "/upload/" + str(new_file_name)即可,简直太牛B了,花了半天发现的问题!
附一个可用的上传代码,tornado 框架下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
def upload(bucketname=BUCKET, savename="/test.txt", filedata=None):
if bucketname and savename and filedata:
if DEBUG:
return None
from bae.api import bcs
mybcs = bcs.BaeBCS(BCSHOST, AK, SK)
e,r = mybcs.put_object(bucketname, savename, filedata)
return r
else:
return "no data"
class UploadPage(BaseHandler):
@tornado.web.authenticated
def get(self):
self.echo("upload-test.html", {"title": "file upload"})
@tornado.web.authenticated
def post(self):
rspd = {'status': 201, 'msg':'ok'}
upfile = self.request.files.get('fileupload', None)
if upfile:
myfile = upfile[0]
try:
file_type = myfile['filename'].split('.')[-1].lower()
new_file_name = "%s.%s"% (str(int(time())), file_type)
except:
file_type = ''
new_file_name = str(int(time()))
d = upload(BUCKET, "/upload/" + str(new_file_name), myfile['body'])
if d is None:
#self.write("upload well done.")
rspd['status'] = 200
rspd['filename'] = myfile['filename']
rspd['msg'] = "http://%s/%s/upload/%s" % (BCSHOST, BUCKET, new_file_name)
else:
#self.write(d)
rspd['status'] = 500
rspd['msg'] = '500 error, pls try it again.'
else:
rspd['msg'] = 'none file uploaded.'
self.set_header('Content-Type','text/html')
self.write(json.dumps(rspd))
return