解码种子文件时出现UnicodeDecodeError

时间:2019-06-25 17:09:28

标签: python-3.x

我正试图从头开始编写torrent应用程序,仅出于学习目的。因此,在阅读Wiki几个小时后,我编写了一些用于解码torrent文件的代码,这些文件使用'Bencoding'“ https://en.wikipedia.org/wiki/Bencode”进行解码。但是不幸的是,我没有注意到字节字符串和python字符串。我的代码可以与torrent数据之类的python字符串一起正常工作,但是当我传递torrent字节数据时,出现了编码错误。

我尝试了“ open(file,'rb',encoding ='utf-8',errors ='ignore')“。它确实将字节字符串更改为python字符串。我还尝试了stakoverflow上的所有可用答案。但是一些数据由于错误而丢失,因此我无法正确解码Torrent数据。请原谅我凌乱的编码,请帮忙...我也阅读了bencoder库,它直接在字节字符串上工作,因此,如果有任何方式我不必重写代码,请...

with open(torrent_file1, 'rb') as _file:
    data = _file.read()

def int_decode(meta, cur):
    print('inside int_decode function')
    cursor = cur
    start = cursor + '1'
    end = start
    while meta[end] != 'e':
        end += 1
    value = int(meta[start:end])
    cursor = end + 1
    print(value, cursor)
    return value, cursor


def chr_decode(meta, cur):
    print('inside chr_decode function')
    cursor = cur
    start = cursor
    end = start
    while meta[end] != ':':
        end += 1
    chr_len = int(meta[start:end])
    chr_start = end + 1
    chr_end = chr_start + chr_len
    value = meta[chr_start:chr_end]
    cursor = chr_end
    print(value, cursor)
    return value, cursor

def list_decode(meta, cur):
    print('inside the list decoding')
    cursor = cur+1
    new_list = list()
    while cursor < (len(meta)):
        if meta[cursor] == 'i':
            item, cursor = int_decode(meta, cursor)
            new_list.append(item)

        elif meta[cursor].isdigit():
            item, cursor = chr_decode(meta, cursor)
            new_list.append(item)

        elif meta[cursor] == 'e':
            print('list is ended')
            cursor += 1
            break

    return (new_list,cursor)

def dict_decode(meta, cur=0, key_=False, key_val=None):
    if meta[cur] == 'd':
        print('dict found')
    new_dict = dict()
    key = key_
    key_value = key_val
    cursor = cur + 1
    while cursor < (len(meta)):

        if meta[cursor] == 'i':
            value, cursor = int_decode(meta, cursor)
            if not key:
                key = True
                key_value = value
            else:
                new_dict[key_value] = value
                key = False

        elif meta[cursor].isdigit():
            value, cursor = chr_decode(meta, cursor)
            if not key:
                key = True
                key_value = value
            else:
                new_dict[key_value] = value
                key = False
        elif meta[cursor] == 'l':
            lists, cursor = list_decode(meta, cursor)             
            if key:
                new_dict[key_value] = lists
                key = False
            else:
                print('list cannot be used as key')


        elif meta[cursor] == 'd':
            dicts, cursor = dict_decode(meta, cursor)
            if not key:
                key=True
                key_value = dicts
            else:
                new_dict[key_value] = dicts
                key=False

        elif meta[cursor] == 'e':
            print('dict is ended')
            cursor += 1
            break


    return (new_dict,cursor)

test = 'di323e4:spami23e4:spam5:helloi23e4:spami232ei232eli32e4:doneei23eli1ei2ei3e4:harmee'
test2 = 'di12eli23ei2ei22e5:helloei12eli1ei2ei3eee'
test3 = 'di12eli23ei2ei22ee4:johndi12e3:dggee'
print(len(test2))
new_dict = dict_decode(data)
print(new_dict)

回溯(最近通话最近):   在第8行的文件“ C:\ Users \ yewaiyanoo \ Desktop \ python \ torrent \ read_torrent.py”     数据= _file.read()   读取文件“ C:\ Users \ yewaiyanoo \ AppData \ Local \ Programs \ Python \ Python37-32 \ lib \ codecs.py”,第701行     返回self.reader.read(size)   读取的文件“ C:\ Users \ yewaiyanoo \ AppData \ Local \ Programs \ Python \ Python37-32 \ lib \ codecs.py”,第504行     newchars,decodedbytes = self.decode(data,self.errors) UnicodeDecodeError:“ utf-8”编解码器无法解码位置204的字节0xad:无效的起始字节

1 个答案:

答案 0 :(得分:0)

Python 3在读取时解码文本文件,在写入时编码。默认编码取自locale.getpreferredencoding(False),对于您的设置,该编码显然返回“ ASCII”。请参见open()函数文档:

在文本模式下,如果未指定编码,则使用的编码取决于平台:调用locale.getpreferredencoding(False)以获取当前的语言环境编码。

您不应使用系统设置,而应使用显式编解码器打开文本文件:

currentFile = open(文件,'rb',encoding ='latin1',errors ='ignore')

设置编码参数以匹配您正在读取的文件。

Python 3支持UTF-8作为默认的源代码。

这同样适用于写入可写文本文件;写入的数据将被编码,并且如果您依靠系统编码,则除非您明确设置了合适的编解码器,否则很可能会收到UnicodeEncodingError异常。编写时使用哪种编解码器取决于您要编写什么文本以及以后打算如何处理文件。

您可能想在Unicode HOWTO中阅读Python 3和Unicode,它解释了源代码的编码以及Unicode数据的读写。