首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >结构,解压缩和打包更改数据。

结构,解压缩和打包更改数据。
EN

Stack Overflow用户
提问于 2021-04-01 03:40:47
回答 2查看 436关注 0票数 1

我目前正在尝试将一些数据打包到脚本"p1.py“中,然后通过管道将其解压到另一个脚本"p2.py”中。管道通信工作得很好,我能够在两个脚本之间发送数据。但是,在解压缩后,数据将被更改。在本例中,我在脚本"p2.py“中这样做,以便打包数据并将其发送到"p1.py”脚本:

代码语言:javascript
复制
COMMAND_STRUCT = struct.Struct(">fB3s")

packed_data = struct.pack(">fB3s",29.1,1,b'3s')
print(packed_data)
#lateral_airspeed_input, drop_package_commanded_byte, _ = COMMAND_STRUCT.unpack(packed_data)
#print(lateral_airspeed_input)

正如我们所看到的,我打印"packed_data“,它被打包为一个浮动,一个字节,然后三个字节。现在,如果我只需将打包的数据打印到我的终端,我就可以得到以下输出:

B‘a\xe8 8\xcc\xcd\x013s\x00’

它只是29.1、1和3个字节的打包形式。如果我取消对最后两行的注释,那么解压缩和打包工作的lateral_airspeed_input将是29.1 -indicating,因为我可以在解压缩后打包和解压缩并获得相同的数据。

现在,这是它变得有趣的地方。当我引入另一个脚本时,我做的事情和这里看到的一样:

代码语言:javascript
复制
        cmd = pilot.stdout.read(COMMAND_STRUCT.size)
        #print(cmd)
        if len(cmd) != COMMAND_STRUCT.size:
            result = CRASHED  # The pilot process must have exited
            break
        lateral_airspeed_input, drop_package_commanded_byte, _ = COMMAND_STRUCT.unpack(cmd)
        print(lateral_airspeed_input)
        lateral_airspeed = max(-30.0, min(30.0, lateral_airspeed_input))
        drop_package_commanded = bool(drop_package_commanded_byte)

这里,将打包的数据读入变量cmd,然后将cmd解压缩到lateral_airspeed_input、drop_package_commanded_byte和_变量。理想情况下,如果我们打印lateral_airspeed_input,我们应该得到29.1。但是,我打印它时会得到7.713289749049545e+20。然而,如果我直接打印cmd,我会得到以下信息:

B“b‘a\x0 8\”b’xcd\xcd\‘b'x013s\x0’b"0'\r\n“

它看起来类似于以前打包的数据--当时我只使用了一个py脚本。由于某种原因,打包的数据会得到所有这些额外的、b“和0\r‘的东西。我认为这破坏了交流,我想知道是否有办法避免这种情况。我宁愿避免这样做,也不愿把代码从线路上去掉。

谢谢你的帮助。我使用子进程管道来管理两个脚本之间的通信,并通过我的windows cmd运行子进程。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-01 05:20:28

正如注释中已经指出的,发送方脚本正在打印字符串的表示形式。也就是说,不是字节序列41 e8 cc cd ... (A..),而是62 21 41 ... (b"A\...)。

此外,在默认情况下,printstdout在文本模式下工作。也就是说,你会遇到麻烦的原始二进制数据。文档说您可以使用stdio的底层缓冲区发送二进制数据:

代码语言:javascript
复制
import sys
sys.stdout.buffer.write(packed_data)
sys.stdout.flush()

您必须使用flush来实际发送数据。否则,只有在遇到换行符(0x0d)时才会编写。

另外,如果您这样做,请确保标准输出没有实际打印到屏幕上。否则你的终端会很快被弄坏。

反之亦然,您应该在接收方脚本:cmd = sys.stdin.buffer.read()中使用二进制读取。

票数 0
EN

Stack Overflow用户

发布于 2021-04-01 04:40:32

我试着根据你提供的资料整理一个样本。

这是脚本p1.py:

代码语言:javascript
复制
import struct

COMMAND_STRUCT = struct.Struct(">fB3s")

packed_data = struct.pack(">fB3s",29.1,1,b'3s')
print(packed_data)

这是脚本p2.py:

代码语言:javascript
复制
import struct
import sys

COMMAND_STRUCT = struct.Struct(">fB3s")
cmd = sys.stdin.read(COMMAND_STRUCT.size)
#print(cmd)
if len(cmd) != COMMAND_STRUCT.size:
    sys.exit(1)
lateral_airspeed_input, drop_package_commanded_byte, _ = COMMAND_STRUCT.unpack(cmd)
print(lateral_airspeed_input)
lateral_airspeed = max(-30.0, min(30.0, lateral_airspeed_input))
drop_package_commanded = bool(drop_package_commanded_byte)

如果我像这样运行,我相信我会得到预期的结果:

代码语言:javascript
复制
%> python2 p1.py | python2 p2.py

29.1000003815

这似乎是想要的结果。你能详细说明一下你的场景和这个小例子有什么不同吗?

更新

按照您之前的评论,我创建了一个新脚本p3.py,如下所示:

代码语言:javascript
复制
import subprocess
import struct
import sys

COMMAND_STRUCT = struct.Struct(">fB3s")
pilot = subprocess.Popen(['python2','./p1.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
cmd = pilot.stdout.read(COMMAND_STRUCT.size)
#cmd = sys.stdin.read(COMMAND_STRUCT.size)
#print(cmd)
if len(cmd) != COMMAND_STRUCT.size:
    sys.exit(1)
lateral_airspeed_input, drop_package_commanded_byte, _ = COMMAND_STRUCT.unpack(cmd)
print(lateral_airspeed_input)
lateral_airspeed = max(-30.0, min(30.0, lateral_airspeed_input))
drop_package_commanded = bool(drop_package_commanded_byte)

当我运行它时,我似乎仍然得到了想要的结果:

代码语言:javascript
复制
%> python2 p3.py

29.1000003815

所以我想我肯定还漏掉了什么。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66898122

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档