所以我试图通过创建一个简单的文件服务器来学习Pyro。我已经实现了一些基本功能,现在我尝试添加文件传输。我已经查看了如何执行此操作的示例(https://github.com/irmen/Pyro4/tree/master/examples/filetransfer),并且它与纯Pyro完成的方式只是返回从文件读取的字节并将其写入接收端。< / p>
这就是我所做的(我知道在发送文件时我真的应该分解文件,但是一旦修复了这个问题我就能做到):
client.py
import Pyro4
server= Pyro4.Proxy("PYRONAME:server")
def download(file_name):
output_file = open(file_name, "wb")
output_file.write(server.download(file_name))
output_file.close()
print "Downloaded file: {}".format(file_name)
server.py
import Pyro4
@Pyro4.expose
class Server(object):
def download(self, file_name):
return open(file_name, "rb").read()
daemon = Pyro4.Daemon()
ns = Pyro4.locateNS()
uri = daemon.register(Server)
ns.register("server", uri)
daemon.requestLoop()
这对于像.txt文档这样的简单文件很有用,但是当我尝试其他文件类型时,例如.pdf,我收到错误:
UnicodeEncodeError: 'ascii' codec can't encode characters in position 11-14: ordinal no in range(128)
我花了一些时间来查找此错误,而我最接近解决方案的方法是在client.py中更改此行:
output_file.write(server.download(file_name))
为:
output_file.write(server.download(file_name).encode("ascii", "replace"))
这可以避免错误,完成下载并提供正确大小的文件。但该文件已损坏且无法打开。
有任何建议如何解决这个问题?如果没有,还有其他方法可以用Pyro实现文件传输吗?
答案 0 :(得分:0)
这是因为file.write
只能写入字节,它还会尝试将输入字符串转换为ascii编码。您的pdf文件具有不同的编码(可能是UTF-8)。你可以试试像
fptr.write(byte_string).encode("utf-8"))
我在处理文件时发现了同样的错误。这是由于除了ascii之外的一些编码。有关详细信息,请参阅此SO Post。有关pdf编码的更多信息,请参阅this pdf。
的第86页答案 1 :(得分:0)
见这里: https://github.com/irmen/Pyro4/blob/master/examples/filetransfer/client.py#L14
如果使用蛇,您需要特别注意正确处理序列化字节。该示例显示了如何执行此操作。
使用pickle或marshal序列化程序时,可以更有效地对二进制数据进行线编码。详情请https://pyro4.readthedocs.io/en/stable/tipstricks.html#binary-data-transfer-file-transfer