一. 前言
在网络传输数据时,数据本质上是以二进制形式进行传输的。无论是传输字节还是传输二进制数据,最终都会转化为二进制进行传输。
所以,从传输速度的角度来看,无论是传输字节还是传输二进制数据,实际上是相同的,没有本质区别。传输速度的快慢主要取决于网络连接的带宽、延迟等因素,而不是数据格式的选择。
在一些特定的应用场景下,可能会使用特定的数据格式进行传输。例如,如果传输的是文本信息,可以选择使用字节流传输;如果传输的是图像或音频等二进制数据,可以选择使用二进制流传输。但这些选择更多是基于数据的特点和处理需求,而不是为了提高传输速度。
二. 各个数据大小测试代码
在Python中,可以使用sys.getsizeof()
函数来计算一个对象的大小(以字节为单位)。
- 使用
json.dumps()
将字典转换为字符串 - 使用
.encode()
方法将字符串转换为字节 - 使用
binascii.hexlify()
将字节转换为十六进制 - 使用
pickle.dumps()
将字典转换为二进制
import json
import pickle
import sys
import binascii
# 示例字典
data = {'name': 'John',
'age': 30,
'city': 'New York',
'角色': '工程师',
}
def calculate_size(data):
# 字典转换为字符
json_str_data = json.dumps(data, ensure_ascii=False)
json_str_size = sys.getsizeof(json_str_data)
# 字典转换为字节
byte_data = json_str_data.encode('utf-8')
byte_size = sys.getsizeof(byte_data)
# 字典转换为十六进制
hex_data = binascii.hexlify(byte_data)
hex_size = sys.getsizeof(hex_data)
# 字典转换为二进制
binary_data = pickle.dumps(data)
binary_size = sys.getsizeof(binary_data)
print(f'dict -> str:{json_str_data}')
print(f'dict -> bytes:{byte_data}')
print(f'dict -> hex:{hex_data}')
print(f'dict -> binary:{binary_data}')
res = {
'data': {
'json_str_data': json_str_data,
'byte_data': byte_data,
'binary_data': binary_data,
'hex_data': hex_data,
},
'size': {
'json_str_size': json_str_size,
'byte_size': byte_size,
'binary_size': binary_size,
'hex_size': hex_size,
},
}
return res
def str2dict(str_data):
# 将JSON字符串转换为字典
my_dict = json.loads(str_data)
return my_dict
def hex2dict(hex_data):
# 将十六进制字符串转换为字节串
bytes_str = binascii.unhexlify(hex_data)
# 将字节串转换为JSON字符串
json_str = bytes_str.decode()
# 将JSON字符串转换为字典
my_dict = json.loads(json_str)
return my_dict
def binary2dict(binary_data):
# 将二进制数据转换为字典
my_dict = pickle.loads(binary_data)
return my_dict
def bytes2dict(bytes_data):
# 将字节流数据转换为字典
my_dict = bytes_data.decode('utf-8')
return my_dict
if __name__ == '__main__':
# 计算大小
res = calculate_size(data)
print("\n====================\n")
print("字典大小:", sys.getsizeof(data))
print("字符大小:", res['size'].get('json_str_size'))
print("字节大小:", res['size'].get('byte_size'))
print("二进制大小:", res['size'].get('binary_size'))
print("十六进制大小:", res['size'].get('hex_size'))
print("\n====================\n")
print("str to dict:", str2dict(res['data'].get('json_str_data')))
print("bytes to dict:", bytes2dict(res['data'].get('byte_data')))
print("hex to dict:", hex2dict(res['data'].get('hex_data')))
print("binary to dict:", binary2dict(res['data'].get('binary_data')))
运行结果
从以上运行结果可以看出,使用转换后字节的大小是最小的,因此常用其作为网络数据传输的格式,一般来说,网络传输数据时推荐使用字节进行表示和计算传输速度。这是因为网络传输通常以字节为单位,而且字节更直接地与计算机系统的存储和传输操作相关联。使用字节作为传输单位更加直观和符合实际。
附上其他数据之间转换的方法
import binascii
import struct
def example(express, result=None):
if result == None:
result = eval(express)
print(express, '==>', result)
if __name__ == '__main__':
print('整数之间的进制转换:')
print('10进制转16进制', end=':')
example("hex(16)")
print("16进制结10进制", end=':')
example("int('0x10', 16)")
print("类似的还有octO, bin()")
print("\n-------------------\n")
print("字符串转整数:")
print("10进制字符串", end=": ")
example("int('10')")
print("16进制字符串", end=": ")
example("int('10', 16)")
print("16进制字符串", end=": ")
example("int('0x10', 16)")
print("\n-------------------\n")
print('字节串转整教:')
print("转义为short型整数", end=": ")
example(r"struct.unpack('< hh', bytes(b'\x01\x00\x00\x00'))")
print("转义为1ong型整教", end=": ")
example(r"struct.unpack('< L', bytes(b'\x01\x00\x00\x00'))")
print("\n====================\n")
print("整数转字节串: ")
print("转为两个字节", end=": ")
example("struct.pack('<HH',1,2)")
print("转为四个字节", end=": ")
example("struct.pack('<LL',1,2)")
print("\n-------------------\n")
print('字符串装字节串:')
print('字符串编码为字节码', end=": ")
example(r"'12abc'.encode(' ascii')")
print('数字或字符数组', end=": ")
example(r"bytes([1, 2,ord('1'), ord('2')])")
print('16进制字符串', end=': ')
example(r"bytes().fromhex('010210')")
print('16进制字符串', end=': ')
example(r"bytes(map(ord,'\x01\x02\x31\x32'))")
print('16进制数组', end=': ')
example(r'bytes([0x01, 0x02, 0x31, 0x32])')
print("\n====================\n")
print("字节串转字符串:")
print('字节码解码为字符串', end=": ")
example(r"bytes(b'\x31\x32\x61\x62').decode('ascii')")
print('字节出传16进制表示,夹带ascii', end=": ")
example(r"str(bytes(b'lx01\x0212'))[2:-1]")
print('字节串转16进制表示, 固定两个字符表示', end=": ")
example(r"str(binascii.b2a_hex(b'\x01\x0212'))[2:-1]")
print("\n====================\n")
=========================================
运行结果
整数之间的进制转换:
10进制转16进制:hex(16) ==> 0x10
16进制结10进制:int('0x10', 16) ==> 16
类似的还有octO, bin()
-------------------
字符串转整数:
10进制字符串: int('10') ==> 10
16进制字符串: int('10', 16) ==> 16
16进制字符串: int('0x10', 16) ==> 16
-------------------
字节串转整教:
转义为short型整数: struct.unpack('< hh', bytes(b'\x01\x00\x00\x00')) ==> (1, 0)
转义为1ong型整教: struct.unpack('< L', bytes(b'\x01\x00\x00\x00')) ==> (1,)
====================
整数转字节串:
转为两个字节: struct.pack('<HH',1,2) ==> b'\x01\x00\x02\x00'
转为四个字节: struct.pack('<LL',1,2) ==> b'\x01\x00\x00\x00\x02\x00\x00\x00'
-------------------
字符串装字节串:
字符串编码为字节码: '12abc'.encode(' ascii') ==> b'12abc'
数字或字符数组: bytes([1, 2,ord('1'), ord('2')]) ==> b'\x01\x0212'
16进制字符串: bytes().fromhex('010210') ==> b'\x01\x02\x10'
16进制字符串: bytes(map(ord,'\x01\x02\x31\x32')) ==> b'\x01\x0212'
16进制数组: bytes([0x01, 0x02, 0x31, 0x32]) ==> b'\x01\x0212'
====================
字节串转字符串:
字节码解码为字符串: bytes(b'\x31\x32\x61\x62').decode('ascii') ==> 12ab
字节出传16进制表示,夹带ascii: str(bytes(b'lx01\x0212'))[2:-1] ==> lx01\x0212
字节串转16进制表示, 固定两个字符表示: str(binascii.b2a_hex(b'\x01\x0212'))[2:-1] ==> 01023132
====================
三. 总结
总结起来,网络传输数据时,
- 无论是字节传输还是二进制传输,传输速度是相同的,可以根据实际需求选择适合的数据格式进行传输。
- 数据是以二进制的形式进行传输,但以字节为单位进行表示和计算传输速度更为常见和推荐。