由于UnicodeDecodeError,Twisted FileSender无法发送二进制文件

时间:2012-01-26 02:34:00

标签: python utf-8 binary twisted

尝试通过HTTP在Twisted中发送文件时,我遇到了一个相当烦人的问题。我是Python的新手(因为这是我第一次尝试除Hello World之外的任何其他事情)。

现在,我很确定当FileSender发送不兼容UTF-8的二进制数据时会出现问题。在通过网络移动图像,视频,可执行二进制文件等文件时,这似乎是一件相当普遍的事情。

在我看来,在初始化时,Twisted缓冲区被初始化为"",这里(我可能在这里很奇怪)是一个UTF-8(或者你的Python的默认字符编码是什么)字符串?...然后,当新数据被添加到缓冲区时,旧缓冲区(UTF-8)与新缓冲区(呃......其他二进制编码?)连接,结果是:

Unhandled Error
Traceback (most recent call last):
Failure: exceptions.RuntimeError: Producer was not unregistered for /vfs/videos/thevid.avi
Unhandled Error
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/twisted/python/log.py", line 84, in callWithLogger
    return callWithContext({"system": lp}, func, *args, **kw)
  File "/usr/lib/python2.7/dist-packages/twisted/python/log.py", line 69, in callWithContext
    return context.call({ILogContext: newCtx}, func, *args, **kw)
  File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 118, in callWithContext
    return self.currentContext().callWithContext(ctx, func, *args, **kw)
  File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 81, in callWithContext
    return func(*args,**kw)
--- <exception caught here> ---
  File "/usr/lib/python2.7/dist-packages/twisted/internet/selectreactor.py", line 146, in _doReadOrWrite
    why = getattr(selectable, method)()
  File "/usr/lib/python2.7/dist-packages/twisted/internet/tcp.py", line 428, in doWrite
    result = abstract.FileDescriptor.doWrite(self)
  File "/usr/lib/python2.7/dist-packages/twisted/internet/abstract.py", line 199, in doWrite
    self.dataBuffer = buffer(self.dataBuffer, self.offset) + "".join(self._tempDataBuffer)
  File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
exceptions.UnicodeDecodeError: 'utf8' codec can't decode byte 0xd3 in position 6: invalid continuation byte
Unhandled Error
Traceback (most recent call last):
Failure: exceptions.RuntimeError: Producer was not unregistered for /vfs/videos/thevid.avi

当然必须有一种方法可靠地设置缓冲区进行二进制数据传输?我的文件发送功能代码如下。我正在使用TxJSONRPC来创建和管理服务器(render方法除外,它被覆盖以处理不仅仅是RPC)。如果需要更多信息(例如关于Request对象或Reactor,我可以去挖掘)。

注意:我很清楚我没有错误处理程序,但此刻对我来说并不重要。一旦我可靠地传输文件,就会添加错误处理!

def writeFile(self, request, location):
    # Setup headers (mime type, filename)
    request.setHeader('Content-Type', mimetypes.guess_type("file://" + location))
    request.setHeader('Content-Disposition', "attachment; filename=" + path.basename(location))

    # Open file
    handle = open(location, "rb")

    # Setup transfer (then cleanup etc)
    d = FileSender().beginFileTransfer(handle, request)
    def fileFinished(ignored):
        handle.close()
        request.finish()
    d.addCallback(fileFinished).addErrback(fileFinished)

0 个答案:

没有答案