首页 > 解决方案 > 通过 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()

标签: pythongziptar

解决方案


没有这样write()的方法tarfile

这个答案显示了正在使用的 add 方法,所以我建议遵循该模式。

TarFile.add(name, arcname=None, recursive=True, exclude=None, filter=None) 将文件名添加到存档中。name 可以是任何类型的文件(目录、fifo、符号链接等)。如果给定,则 arcname 指定存档中文件的替代名称。默认情况下递归添加目录。这可以通过将 recursive 设置为 False 来避免。如果给出了 exclude,它必须是一个接受一个文件名参数并返回一个布尔值的函数。根据这个值,相应的文件要么被排除(真),要么被添加(假)。如果指定了过滤器,它必须是一个接受 TarInfo 对象参数并返回更改后的 TarInfo 对象的函数。如果它返回 None,则 TarInfo 对象将从存档中排除。有关示例,请参见示例。


推荐阅读