背景
我将数据转换为二进制,因为服务器端需要二进制类型。
的问题:
如何将数字列表转换为String然后重新构建列表?
文件内容:
1 1 1
1 2 1
1 3 1
1 4 1
1 5 1
1 6 1
1 7 1
1 8 1
1 9 1
1 10 1
1 11 1
1 12 1
1 13 1
1 14 1
1 15 1
在客户端:我正在读取整个文件,将每个值附加到列表中。然后将列表转换为数组,在将数据发送到服务器之前将其转换为字符串。
在服务器中:我将字符串映射回值列表。然后使用(x, y, w)
将列表转换为元组grouper
的列表。然后将(x, y, z)
提供给Point
,并将新构造的对象附加到列表中。
注意我无法使用bytearray
,因为这是一个人工数据样本,我的数字比byte
所代表的要多得多。
的代码:
from itertools import izip_longest
import array
def grouper(iterable, n, fillvalue=None):
#Collect data into fixed-length chunks or blocks
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
class Point:
def __init__(self, x, y, w):
self.x = x
self.y = y
self.w = w
if __name__ == "__main__":
myList = []
listOfObjects = []
with open('data10mb.txt') as f:
for line in f:
s = line.split()
x, y, w = [int(v) for v in s]
myList.append(x)
myList.append(y)
myList.append(w)
L = array.array('h', myList).tostring()
发送到服务器的数据
收到的数据
myList = list(map(ord, list(L)))
myList = list(grouper(myList, 3))
s = len(myList)
for i in range (0, s):
x, y, w = myList[i]
obj = Point(x, y, w)
listOfObjects.append(obj)
预期输出:
1 <---- first line in file
1
1
--------
1 <--- sixth line in file
7
1
实际输出:
1
0
1
1
0
4
我不确定我做错了什么..我4天前问了this问题。 "How to convert .txt file to a binary object"
。
服务器指定应发送的数据为:binary: A byte array
。我不能在这里有一个简单的bytearray
因为python bytearray仅限于保存数字0-256
而且我文件中表示的数字要大得多。
我应该使用什么?至于上半部分,它的清晰数据是混合的,我在服务器端没有正确解析,或者我在代码中做错了,我看不到它......
修改<!/强>
我已经尝试发送列表而不是字符串,但服务器不接受。
TypeError:write()参数1必须是字符串或缓冲区,而不是列表。
提前致谢!
答案 0 :(得分:1)
在您的代码中:
L = array.array('h', myList).tostring()
您正在创建一个打包为两个字节整数的字节串。在服务器端,您然后使用list(L)
,L
的每个元素生成一个列表,但在这种情况下,它不会保留2字节的打包,因为它将bytestring中的每个元素视为单个字节,例如:
>>> import array
>>> a = array.array('h', [1234, 5678])
>>> s = a.tostring()
>>> s
b'\xd2\x04.\x16'
>>> list(s)
[210, 4, 46, 22] # oops - wrong!
因此,从源数据重建数组以获取您发送的内容。
>>> array.array('h', s)
array('h', [1234, 5678]) # better!
另请注意,在您的评论中,您说范围高达1,000,000 - &#39; h&#39; format是一个2字节有符号整数,所以你需要使用&#39; l&#39;对于签名长而不是足够代表值...(请参阅array documentation中的类型代码以获取可用选项)
to_send = array.array('l', [1000000, 12345]).tostring()
recieved = array.array('l', to_send)