【问题标题】:Python 3 itertools.islice continue despite UnicodeDecodeError尽管 UnicodeDecodeError,Python 3 itertools.islice 继续
【发布时间】:2016-02-20 09:37:18
【问题描述】:

我有一个监控日志文件的 python 3 程序。该日志包括用户编写的聊天消息等。日志是由我无法更改的第三方应用程序创建的。

今天一个用户写了“텋��텋��”,导致程序崩溃并出现以下错误:

future: <Task finished coro=<updateConsoleLog() done, defined at /usr/local/src/bserver/logmonitor.py:48> exception=UnicodeDecodeError('utf-8',...
say "\xed\xa0\xbd\xed\xb1\x8c"\r\n', 7623, 7624, 'invalid continuation byte')>
Traceback (most recent call last):
File "/usr/lib/python3.4/asyncio/tasks.py", line 238, in _step
result = next(coro)
File "/usr/local/src/bserver/logmonitor.py", line 50, in updateConsoleLog
server_events = self.console.getUpdate()
File "/usr/local/src/bserver/console.py", line 79, in getUpdate
return self.read()
File "/usr/local/src/bserver/console.py", line 90, in read
for line in itertools.islice(log_file, log_no, None):
File "/usr/lib/python3.4/codecs.py", line 319, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xed in position 7623: invalid continuation byte
ERROR:asyncio:Task exception was never retrieved

使用'file -i log.file'我确定日志文件是us-ascii。这不应该是问题,因为 ascii 是 utf-8 的子集(据我所知)。

由于这种情况很少发生,而且我不介意丢失该用户输入的任何内容,我是否可以忽略此行或无法解码的特定字符并继续阅读其余部分文件?

我考虑过使用try: ... except UnicodeDecodeError as ...,但这意味着我无法在错误发生后读取日志文件中的任何内容。

代码

def read(self):
    log_no = self.last_log_no
    log_file = open(self.path, 'r')
    server_events = []
    starting_log_no = log_no
    for line in itertools.islice(log_file, log_no, None): //ERROR
        server_events.append(line)
        print(line.replace('\n', '').replace('\r', ''))

        log_no += 1
        self.last_log_no = log_no
    if (starting_log_no < log_no):
        return server_events
    return False

任何帮助或建议将不胜感激!

【问题讨论】:

    标签: python utf-8 character-encoding ascii itertools


    【解决方案1】:

    字节串\xed\xa0\xbd\xed\xb1\x8c 不是utf-8 有效。 us-ascii 也不是,因为 us-ascii 只能是 7 位长;即\x8c 大于 127。

    不要忽略UnicodeDecodeError,而是尝试使用支持所有8位字节的编码打开文件(例如latin-1):

    log_file = open(self.path, 'r' encoding='latin-1')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-29
      • 1970-01-01
      • 2012-09-16
      • 2018-02-21
      • 1970-01-01
      相关资源
      最近更新 更多