Python工具箱系列(三十七)

二进制文件操作(上)

python比较擅长与文本相关的操作。但现实世界中,对于非文本消息的处理也很普遍。例如:

◆通过有线、无线传递传感器获得的测量数据。

◆卫星通过电磁波发送测量数据。

◆数据中心的数万台服务器发送当前CPU的占用率信息、内存占用量等众多指标数据。

以上数据,当然可以以文本方式发送,但是对于带宽的占用惊人。假设某个对于PM2.5进行测量的传感器,每隔一秒发送一次测量数据,以文本方式发送消息,内容如下:

"counter: 1, pm25: 170.24119426834042, timestamp: 2022-07-24 08:52:11.138894+00:00"

以上消息占用了81个字节。而如果能够按照约定的格式直接发送二进制数据,则只需要20个字节,可以大幅提升传输效率。此外,以文本方式在本地保存传感器数据,则一天就需要81*86400/1024=6834M字节,对于传感器这种体积小巧的嵌入式系统,存储空间极为有限,很快就会空间耗尽。因此,对非文本数据直接保存与读取非常有必要。下面的代码演示了传感器类,以及传感器测量数据的二进制文件存储与读取的基本操作。

import binascii
import random
import struct
from datetime import datetime
from io import BytesIO
from time import sleepimport arrowclass sensordata_v1():def __init__(self):utc = arrow.utcnow()self._timestamp = utc.to('Asia/Shanghai')@propertydef counter(self) -> int:"""计数器Returns:int: 从0开始的计数器"""return self._counter@counter.setterdef counter(self, value: int):self._counter = value@propertydef pm25(self) -> float:"""PM25测量值Returns:float: pm25的当前测量值"""return self._pm25@pm25.setterdef pm25(self, value: float):self._pm25 = value@propertydef timestamp(self) -> datetime:"""当前时点Returns:datetime: 当前的时间"""return self._timestamp.datetimedef __str__(self):"""以文字输出相关内容Returns:string: 说明性文字"""return f"counter: {self.counter}, pm25: {self.pm25}, timestamp: {self.timestamp}"def __repr__(self):"""输出字节流的16进制内容Returns:string: 16进制显示相关数值"""return str(binascii.hexlify(self.toBytes()))def toBytes(self):"""将相关数据转换成为bytes,便于网络传输或者写入文件Returns:bytes: 整合测量数据到字节流中"""with BytesIO() as byio:byio.write(struct.pack('<i', self.counter))byio.write(struct.pack('<d', self.pm25))byio.write(struct.pack('<d', self._timestamp.timestamp()))return byio.getvalue()def fromBytes(self, data):"""从字节流中解出相关值Args:data (bytes): 待解析的字节流"""self.counter, self.pm25, st = struct.unpack('<idd', data)self._timestamp = arrow.get(st)def toFile(filename):"""向二进制文件中写入数据Args:filename (string): 文件名称"""with open(filename, 'wb') as myfile:for index in range(10):sensor_obj = sensordata_v1()sensor_obj.counter = indexsensor_obj.pm25 = random.uniform(0, 300)data = sensor_obj.toBytes()myfile.write(data)sleep(1)def fromFile(filename):"""从二进制文件中获得保存的信息,并且重建对象Args:filename (string): 文件名称"""with open(filename, 'rb') as myfile:fmt = struct.Struct('<idd')datalen = fmt.sizefor index in range(10):data = myfile.read(datalen)sensor_obj = sensordata_v1()sensor_obj.fromBytes(data)print(sensor_obj)datafilename = r"d:\dev\sensor.dat"
toFile(datafilename)
fromFile(datafilename)

其中arrow是非常值得推荐的时间处理框架。python有内置的时间处理框架,功能非常完善,但失之于乱与杂,掌握起来非常不易。而arrow则非常人性化,做到了拿来即用。其安装过程非常简单,直接pip install arrow即可。在示例程序中,为了能够方便存储,我们将时间戳直接用UNIX的timestamp来表示,转换后为了保持精度,本例使用double(8字节)存储,如果要求不高,可以改为float(4字节)。

sensordata_v1类使用@property装饰器来定义属性。总共有3个属性:

◆counter-计数器。从0开始计数累加,后续保存到数据库中时也方便检索。

◆pm25-PM2.5测量值。在示例代码中使用random.uniform模拟一个0到300的随机浮点值,没有什么太大的意义,保证每次不同即可。

◆timestamp-数据采集时的对应时间。

str类函数

可以自定义,本例中用它来直观的表示当前的采集值。当对sensordata_v1类的实例打印时,就会自动调用这个函数。

repr类函数

可以自定义,本例中用它来演示转换成为字节流bytes时的16进制值。对于程序员来说,16进制来表示字节是比较自然的。

toBytes类函数具体展示了如何将类的属性值转换成为二进制字节流,主要依靠python内置的struct模块。在内存中模拟文件打开一个BytesIO,并且依次写入struct.pack编码后的字节流,最终统一输出。

fromBytes类函数具体展示了如何从字节流反解成为对象的属性值。struct.pack与struct.unpack成对出现。

toFile函数将编码好的字节流写入二进制文件。写入的模式为'wb',其中w代表全覆盖写入的意思,b代表二进制模式的意思。fromFile负责从二进制文件读回保存的字节流,重新生成各个sensordata_v1对象。

生成的二进制文件,可以使用UltraEditor、InHex等。也可以直接使用vscode自带的2进制文件浏览器扩展Hex Editor,显示效果如下图所示:

 从图中可以看出,二进制文件确实节省空间,但人类不容易理解,必然借助于专用工具与代码来管理。但即使计算机与网络能力强悍如斯,二进制文件与网络上的字节流仍然必不可少,不可替代。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/2693.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python】Python进阶系列教程--Python AI 绘画(二十)

文章目录 前言Windows 环境安装Civitai 介绍 前言 往期回顾&#xff1a; Python进阶系列教程-- Python3 正则表达式&#xff08;一&#xff09;Python进阶系列教程-- Python3 CGI编程&#xff08;二&#xff09;Python进阶系列教程-- Python3 MySQL - mysql-connector 驱动&a…

【单片机】STM32F103C8T6单片机,OLED 1.3寸 IIC OLED,STM32F103单片机,I2C OLED

文章目录 main.coled.coled.hOLED_Font.h 效果&#xff1a; main.c #include "sys.h" #include "usart.h" #include "OLED.h"int main(void) {NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* 设置NVIC中断分组2:2位抢占优…

ELK 多用户登录

先搭建ELK集群环境 请移步至&#xff1a;FilebeatELK 搭建日志收集平台 ES开启TLS加密通信与身份认证 进入ES集群任意一台安装目录&#xff0c;生成ca证书 这里最好使用ES启动账号操作&#xff0c;证书生成过程中一直回车到完成&#xff0c;不要去输入密码。 # 生成CA证书 bi…

【软考网络管理员】2023年软考网管初级常见知识考点(23)- 路由器的配置

涉及知识点 华为路由器的配置&#xff0c;华为路由器命令大全&#xff0c;软考大纲路由命令&#xff0c;静态路由和动态路由的配置命令&#xff0c;软考网络管理员常考知识点&#xff0c;软考网络管理员网络安全&#xff0c;网络管理员考点汇总。 原创于&#xff1a;CSDN博主-…

SQL-每日一题【184. 部门工资最高的员工】

题目 表&#xff1a; Employee 表&#xff1a; Department 编写SQL查询以查找每个部门中薪资最高的员工。 按 任意顺序 返回结果表。 查询结果格式如下例所示。 示例 1: 解题思路 前置知识 1.rank() over的用法 作用&#xff1a;查出指定条件后的进行排名&#xff0c;条件相同…

如何克服自动化测试中的壁垒和问题?

随着自动化测试技术的快速发展和普及&#xff0c;自动化测试已经成为各个行业广泛应用的重要测试手段。然而&#xff0c;自动化测试中仍然存在壁垒和问题&#xff0c;这些问题可能对测试效果产生影响&#xff0c;甚至会影响整个项目的进程。在本文中&#xff0c;我们将探讨如何…

QT5.12安卓环境的搭建(转载保存留档查看)

1. QT环境搭建 Qt 5.12.6安装的时候 添加 “Android ARM64-v8a”&#xff0c;也可以添加 “Android ARMv7” 。 &#xff08;其它为搭建qgc时需要添加的&#xff09; 2. Android 环境搭建 QT官方的指导&#xff1a; Qt 5.12 Getting Started with Qt for Android Qt 5.15 …

【CGAL】Clion+vcpkg+MacOS M2

安装brew 链接如下&#xff1a; MacBook使用笔记&#xff1a;安装Homebrew&#xff08;M1&#xff09; - 知乎 打开mac终端&#xff0c;输入&#xff1a; /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 这个是国内镜…

Haproxy开源负载均衡部署

第一步环境准备&#xff1a; systemctl stop firewalld setenforce 0 systemctl disable firewalld.service #设置开机不启动防火墙sed -i s/SELINUX.*/SELINUXdisabled/ /etc/sysconfig/selinux #设置开机不启动防火墙iptables -F centos7服务器 haproxy 192.168…

Pytest+selenium+allure+Jenkins自动化测试框架搭建及使用

一、 环境搭建 1. Python下载及安装 Python可应用于多平台包括windows, Linux 和 Mac OS X, 本文主要介绍windows环境下。你可以通过终端窗口输入 "python" 命令来查看本地是否已经安装Python以及Python的安装版本。 如未安装python, 推荐下载python 3.8.3以…

【冒泡排序】

前言 在计算机科学中&#xff0c;排序算法是一种常见且重要的算法。排序算法的目标是将一组无序的数据按照一定的规则进行重新排列&#xff0c;以便更方便地进行搜索、查找或其他操作。 冒泡排序&#xff08;Bubble Sort&#xff09;是最简单的排序算法之一&#xff0c;它的原…

思维导图对我生活以及工作的帮助(用户投稿)

作为一名白领&#xff0c;我每天都面临着各种各样的工作和生活压力。 为了更好地应对这些挑战&#xff0c;我开始尝试使用思维导图来帮助自己更好地组织和管理各种信息和任务。其中一款非常优秀的软件就是ProcessOn思维导图&#xff0c;它为我的工作和生活带来了很多便利和帮助…