python 七牛工具包 中文路徑亂碼解決方案

版本:qiniu==7.0.8
環境:Mac os 10.12.3

最近寫了一套七牛上傳的工具包,涉及到中文歌曲路徑,就會報錯:
  File "/Users/ouyang/PycharmProjects/myApp/venv/lib/python2.7/site-packages/qiniu/services/storage/upload_progress_recorder.py", line 34, in get_upload_record
    record_file_name = base64.b64encode(key.encode('utf-8')).decode('utf-8')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 5: ordinal not in range(128)
查看問題代碼位於/Users/ouyang/PycharmProjects/myApp/venv/lib/python2.7/site-packages/qiniu/services/storage/uploader.py”:
def get_upload_record(self, file_name, key):
    key = '{0}/{1}'.format(key, file_name)

    record_file_name = base64.b64encode(key.encode('utf-8')).decode('utf-8')

    upload_record_file_path = os.path.join(self.record_folder,
                                           record_file_name)
    
    if not os.path.isfile(upload_record_file_path):
        return None
    with open(upload_record_file_path, 'r') as f:
        json_data = json.load(f)
    return json_data
上面的file_name是unicode字符串,但key='{0}/{1}’.format(key, file_name)這裏是容不下unicode字符串的。

解決方案一
我們自己把所有的設計unicode的編碼都手動改成utf-8,然後保證傳進來的都是utf-8即可。
只需要修改兩個文件的部分代碼即可:
upload_process_recorder.py:
# -*- coding: utf-8 -*-

import base64
import json
import os
import tempfile


class UploadProgressRecorder(object):
    """持久化上傳記錄類

    該類默認保存每個文件的上傳記錄到文件系統中,用於斷點續傳
    上傳記錄爲json格式:
    {
        "size": file_size,
        "offset": upload_offset,
        "modify_time": file_modify_time,
        "contexts": contexts
    }

    Attributes:
        record_folder: 保存上傳記錄的目錄
    """
    def __init__(self, record_folder=tempfile.gettempdir()):
        self.record_folder = record_folder

    def get_upload_record(self, file_name, key):
        if type(file_name) is unicode:
            file_name = file_name.encode('utf-8')
        key = '{0}/{1}'.format(key, file_name)

        # record_file_name = base64.b64encode(key.encode('utf-8')).decode('utf-8')
        record_file_name = base64.b64encode(key)
        record_file_name = record_file_name.replace('/', '_') # 去掉/字符的出現在路徑的可能性

        upload_record_file_path = os.path.join(self.record_folder,
                                               record_file_name)
        print record_file_name

        if not os.path.isfile(upload_record_file_path):
            return None
        with open(upload_record_file_path, 'r') as f:
            json_data = json.load(f)
        return json_data

    def set_upload_record(self, file_name, key, data):
        if type(file_name) is unicode:
            file_name = file_name.encode('utf-8')

        key = '{0}/{1}'.format(key, file_name)
        # record_file_name = base64.b64encode(key.encode('utf-8')).decode('utf-8')
        record_file_name = base64.b64encode(key)
        record_file_name = record_file_name.replace('/', '_')

        upload_record_file_path = os.path.join(self.record_folder,
                                               record_file_name)
        with open(upload_record_file_path, 'w') as f:
            json.dump(data, f)

    def delete_upload_record(self, file_name, key):

        if type(file_name) is unicode:
            file_name = file_name.encode('utf-8')

        key = '{0}/{1}'.format(key, file_name)
        record_file_name = base64.b64encode(key)
        record_file_name = record_file_name.replace('/', '_')

        # record_file_name = base64.b64encode(key.encode('utf-8')).decode('utf-8')
        record_file_path = os.path.join(self.record_folder,
                                        record_file_name)
        os.remove(record_file_path)
uploader.py:
這個只加了兩行(143-144):
if type(self.file_name) is unicode:
    self.file_name = self.file_name.encode('utf-8')

解決方案二
# 修改文件名爲非中文,不然七牛那邊好麻煩...歌曲上傳到七牛
song_path = full_file_path.replace(single_name, 'a.mp3')
os.rename(full_file_path, full_file_path.replace(single_name, 'a.mp3’))
# 再把文件名改回去...
os.rename(full_file_path.replace(single_name, 'a.mp3'), full_file_path)



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章