Python通过MQTT收发tar.gz文件出错,求正确处理方法
解决MQTT收发.tar.gz文件后无法解压的问题
让我们一步步拆解你的问题,先解决最直接的报错,再修复文件损坏的根源:
1. 接收端的直接错误:AttributeError: 'TarFile' object has no attribute 'write'
你犯了一个基础使用错误:tarfile.open()返回的TarFile对象是用来创建或读取tar归档内容的,它没有write()方法来直接写入字节流。而你接收的msg.payload已经是一个完整的.tar.gz文件的二进制数据,根本不需要通过tarfile模块处理,直接用普通文件的二进制写入模式保存即可。
修正后的接收端代码:
from time import gmtime, strftime import socket import paho.mqtt.client as mqtt today = strftime("%Y-%m-%d-%H:%M:%S", gmtime()) def on_connect(client, userdata, flags, rc): print("Connected with result code "+str(rc)) client.subscribe("Backup", qos=2) def on_message(client, userdata, msg): print("Topic : ", msg.topic) # 直接用二进制写入模式保存完整的payload with open("/backups/daily.%s.tar.gz" % today, "wb") as f: f.write(msg.payload) print("文件保存完成") clientid = socket.gethostname() print(clientid) client = mqtt.Client(clientid, False) client.on_connect = on_connect client.on_message = on_message client.connect("192.168.1.1", 1883, 60) client.loop_forever()
2. 发送端的隐藏问题:破坏了.tar.gz文件结构
你的发送端代码里有一个致命错误:你把字符串"filename"和文件内容拼接成了byteArr,这会导致接收的文件开头多了filename这几个字符,直接破坏了.tar.gz的文件头结构,导致解压失败。
另外,发送文件时不需要额外拼接任何前缀,直接发送读取到的二进制文件内容即可。同时建议用with语句管理文件,避免资源泄漏。
修正后的发送端代码:
import subprocess import paho.mqtt.client as mqtt def on_publish(mosq, userdata, mid): mosq.disconnect() client = mqtt.Client() client.connect("192.168.1.1", 1883, 60) client.on_publish = on_publish # 获取目标文件名 ps = subprocess.Popen(('ls', '/new/backups/ready/'), stdout=subprocess.PIPE) output = subprocess.check_output(('head', '-1'), stdin=ps.stdout) ps.wait() filename = '/new/backups/ready/'+output.rstrip() print(f"准备发送文件: {filename}") # 读取文件二进制内容并发送 with open(filename, "rb") as f: fileContent = f.read() # 直接发送文件二进制数据,不要拼接额外内容 client.publish("Backup", fileContent, qos=2) client.loop_forever()
额外说明
你提到每个待发送的.tar.gz是由3个.tar.gz压缩而成的,这完全没问题——只要原始的.tar.gz本身是合法的,通过MQTT完整收发二进制数据后,就能正常解压。问题的核心是你之前的代码既错误使用了tarfile模块,又在发送时破坏了文件结构。
内容的提问来源于stack exchange,提问作者SomeGuy
相关产品推荐
相关产品推荐

