我目前正在从事一个涉及一些非常远程的数据收集的项目。每天结束时,简短的摘要都会通过卫星连接发送回服务器。
由于通过卫星发送数据非常昂贵,我希望数据尽可能紧凑。另外,我正在使用的服务仅允许以以下两种格式发送数据:ASCII,十六进制。我将发送的大多数数据都由浮点数组成,浮点数的精度应尽可能高而不会占用太多空间。
下面我有当前正在使用的版本,但是应该有一种更有效的方式来存储数据。任何帮助将不胜感激。
import ctypes
#------------------------------------------------------------------
#This part is known to the client as well as the server
class my_struct(ctypes.Structure):
_pack_ = 1
_fields_ = [('someText', ctypes.c_char * 12),
('underRange', ctypes.c_float),
('overRange', ctypes.c_float),
('TXPDO', ctypes.c_float)]
def print_struct(filled_struct):
d = filled_struct
for name,typ in d._fields_:
value = getattr(d, name)
print('{:20} {:20} {}'.format(name, str(value), str(typ)))
#------------------------------------------------------------------
# This part of the code is performed on the client side
#Filling the struct with some random data, real data will come from sensors
s = my_struct()
s.someText = 'Hello World!'.encode()
s.underRange = 4.01234
s.overRange = 4.012345
s.TXPDO = 1.23456789
#Rounding errors occurred when converting to ctypes.c_float
print('Data sent:')
print_struct(s)
data = bytes(s) #Total length is 24 bytes (12 for the string + 3x4 for the floats)
data_hex = data.hex() #Total length is 48 bytes in hexadecimal format
#Now the data is sent over a satellite connection, it should be as small as possible
print('\nLength of sent data: ',len(data_hex),'bytes\n')
#------------------------------------------------------------------
# This part of the code is performed on the server side
def move_bytes_to_struct(struct_to_fill,bytes_to_move):
adr = ctypes.addressof(struct_to_fill)
struct_size = ctypes.sizeof(struct_to_fill)
bytes_to_move = bytes_to_move[0:struct_size]
ctypes.memmove(adr, bytes_to_move, struct_size)
return struct_to_fill
#Data received can be assumed to be the same as data sent
data_hex_received = data_hex
data_bytes = bytes.fromhex(data_hex_received)
data_received = move_bytes_to_struct(my_struct(), data_bytes)
print('Data received:')
print_struct(data_received)
答案 0 :(得分:2)
我不知道您是否使事情变得有些复杂。 struct模块将使您可以做很多事情,但更简单:
struct.pack("fffs12", 4.01234, 4.012345, 1.23456789, 'Hello World!'.encode())
这当然取决于您知道字符串的长度,但是您也不必在意:
struct.pack("fff", 4.01234, 4.012345, 1.23456789) + 'Hello World!'.encode()
但是,关于更有效地保存内容: 您对数据了解的越多,可以采取的捷径就越多。 字符串仅是ascii吗?您可以将每个字符压缩为7位,甚至6位。 这可能会使您的12个字节的字符串变为9。
如果您知道浮标的范围,则也可以对其进行修剪。
如果您可以发送更大的批次,压缩也可能会有所帮助。