python - 通过 MQTT 发送和接收 tarfile - python
问题描述
我可以使用 python 脚本通过 MQTT 发送一个压缩包,但是当我收到它时,我去解压缩它并收到一个错误。跟踪错误后,输入流似乎没有压缩文件,因此即使扩展名是 .tar.gz,它也不是实际的 .tar.gz 文件。
这听起来很傻,但最重要的问题是“我如何写入 tar 文件或如何‘接收’一个 tar 文件,以便它仍然是正确的 .tar.gz 格式以便以后解包?”
我在这里查看了 tarfile 模块,它帮助了一点,以及这里和这里的一些问题...... 但无法确定解决方案。值得注意的是,每个 .tar.gz 实际上是将 3 个 .tar.gz 文件压缩为一个 - 不确定这是否相关。
我的代码:
from time import gmtime, strftime
import socket
import paho.mqtt.client as mqtt
import tarfile
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
f = tarfile.open("/backups/daily.%s.tar.gz" % today, "w:gz")
f.write(msg.payload)
f.close()
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()
还有我的错误信息:
Connected with result code 0
Topic : Backups
Traceback (most recent call last):
File "/scripts/filereceiver.py", line 37, in <module>
client.loop_forever()
File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1481, in loop_forever
rc = self.loop(timeout, max_packets)
File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1003, in loop
rc = self.loop_read(max_packets)
File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1284, in loop_read
rc = self._packet_read()
File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1849, in _packet_read
rc = self._packet_handle()
File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 2309, in _packet_handle
return self._handle_pubrel()
File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 2529, in _handle_pubrel
self._handle_on_message(self._in_messages[i])
File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 2647, in _handle_on_message
self.on_message(self, self._userdata, message)
File "/root/filereceiver.py", line 25, in on_message
f.write(msg.payload)
AttributeError: 'TarFile' object has no attribute 'write'
我不认为 MQTT 与它有任何关系,它只是我的脚本中缺少的东西?
编辑:
这是发送代码。它的工作原理是它可以发送/接收字节,并且在与非 tar 一起使用时效果很好。问题也可能在这里,而不是接收代码,尽管这对我来说似乎不太可能。
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
#output = subprocess.check_output(['ls', '-l', ])
#print(output)
ps = subprocess.Popen(('ls', '/new/backups/ready/'), stdout=subprocess.PIPE)
output = subprocess.check_output(('head', '-1'), stdin=ps.stdout)
ps.wait()
print(output)
filename = '/new/backups/ready/'+output.rstrip()
f=open(filename, "rb")
fileContent = f.read()
byteArr = "filename" +bytearray(fileContent)
client.publish("Updates",byteArr,2)
client.loop_forever()
解决方案
没有这样write()
的方法tarfile
。
这个答案显示了正在使用的 add 方法,所以我建议遵循该模式。
TarFile.add(name, arcname=None, recursive=True, exclude=None, filter=None)
将文件名添加到存档中。name 可以是任何类型的文件(目录、fifo、符号链接等)。如果给定,则 arcname 指定存档中文件的替代名称。默认情况下递归添加目录。这可以通过将 recursive 设置为 False 来避免。如果给出了 exclude,它必须是一个接受一个文件名参数并返回一个布尔值的函数。根据这个值,相应的文件要么被排除(真),要么被添加(假)。如果指定了过滤器,它必须是一个接受 TarInfo 对象参数并返回更改后的 TarInfo 对象的函数。如果它返回 None,则 TarInfo 对象将从存档中排除。有关示例,请参见示例。
推荐阅读
- php - 从本地主机到服务器的 Aframe
- openstreetmap - 在线地图和数据库之间缺少 OpenStreetMap 数据
- sql-server - ORA-01005: 给出了空密码;登录被拒绝”尝试时出错
- c++ - 字符向量的奇怪输出
- azure - Azure 安全中心 ARM 模板为所有资源启用标准计划
- r - 在 R h2o.glm 中仅使用截距构建回归(空模型)
- r - Number of specific sequences in vector
- c - send() on a UDS socket returns without sending the entire data. Why?
- javascript - ReactJS -Throw Submission Error with axios response
- laravel - How to Convert received data from Database to string in laravel?