首页 > 编程语言 >Python存储与读写二进制文件

Python存储与读写二进制文件

时间:2024-09-10 17:50:53浏览次数:3  
标签:tmp 存储 字节 Python 读写 二进制 PAGE SIZE

技术背景

一般情况下我们会选择使用明文形式来存储数据,如json、txt、csv等等。如果是需要压缩率较高的存储格式,还可以选择使用hdf5或者npz等格式。还有一种比较紧凑的数据存储格式,就是直接按照二进制格式存储。这种格式下,存储的数据之间没有间隔符,在没有压缩的情况下应该是体积最小的存储类型。

使用方法

在Python中,我们可以使用numpy.tofile()功能,直接将numpy数组类型存储到一个二进制文件中。读取的时候,虽然可以直接使用open(file_name, ‘rb’)来进行读取,但是为了适配大量IO的场景,这里我们使用内存映射mmap的形式来进行数据读取。

完整示例

如下是一个完整的示例代码,相关的功能直接用注释的形式在代码中标记:

import numpy as np
import mmap
import resource
# 获取页数据量大小(单位:字节)
PAGE_SIZE = resource.getpagesize()
# 定义单精度浮点数数据占用字节(单位:字节)
DATA_SIZE = 4
# 计算页存储数据数量(num_float32)
PAGE_FNUM = int(PAGE_SIZE/DATA_SIZE)
print ("The PAGE_SIZE is: {}".format(PAGE_SIZE))
print ("Corresponding float32 numbers should be: {}".format(PAGE_FNUM))
# 生成示例数据,使用PAGE_FNUM+4大小的数据量定义两页数据
tmp_arr = np.arange(PAGE_FNUM+4).astype(np.float32)
# 数据存储路径
tmp_file = '/tmp/tmp.dat'
# 将数组存储到二进制文件中
tmp_arr.tofile(tmp_file)
# 每次从二进制文件中读取4个数据
READ_NUM = 4
with open(tmp_file, 'rb') as file:
    # 第一页数据的内存映射
    mm = mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ, offset=0)
    # 第一页数据的1、2、3、4位数据
    print (np.frombuffer(mm.read(DATA_SIZE*READ_NUM), dtype='<f4'))
    # 第一页数据的5、6、7、8位数据
    print (np.frombuffer(mm.read(DATA_SIZE*READ_NUM), dtype='<f4'))
    # 第二页数据的内存映射
    mm = mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ, offset=PAGE_SIZE)
    # 第二页数据的1~4位数据
    print (np.frombuffer(mm.read(DATA_SIZE*READ_NUM), dtype='<f4'))
    # 第二页数据的5~8位数据
    print (np.frombuffer(mm.read(DATA_SIZE*READ_NUM), dtype='<f4'))
    # 关闭内存映射
    mm.close()
# 退出文件IO

该脚本的输出结果为:

The PAGE_SIZE is: 4096
Corresponding float32 numbers should be: 1024
[0. 1. 2. 3.]
[4. 5. 6. 7.]
[1024. 1025. 1026. 1027.]
[]

结果解析

我们打印的第一个数据是页大小,这里显示是4096个字节。而一个单精度浮点数占4个字节,所以一页存了1024个单精度浮点数,也就是第二个打印输出的结果。由于我们定义的numpy数组是一个从0开始的递增数组,因此第一页数据的前8位数字就是从0到7。而第二页的数据是1024~1027一共4个浮点数,占16个字节。所以我们在第二页第二次使用numpy.frombuffer()去读取数据的时候,得到的是一个空的数组。此外我们可以查看一下这个二进制文件的大小:

In [1]: import os

In [2]: os.path.getsize('/tmp/tmp.dat')
Out[2]: 4112

一共是4112个字节,刚好是4096+16个字节。

总结概要

本文介绍了一种在Python中将Numpy数组转存为一个紧凑的二进制格式的文件,及其使用内存映射的形式进行读取的方案。一个二进制的数据流,不仅可以更加方便页形式的内存映射,相比于传统的Numpy单精度浮点数数组还有一个可哈希的特性。总体来说是一个对于高性能计算十分友好的存储格式,在cudaSPONGE中作为一个分子动力学模拟轨迹输出的格式使用。


最后这里免费分享给大家一份Python全台学习资料,包含视频、源码。课件,希望能帮到那些不满现状,想提升自己却又没有方向的朋友,也可以和我一起来学习交流呀。
编程资料、学习路线图、源代码、软件安装包【点击这里】领取!

Python所有方向的学习路线图,清楚各个方向要学什么东西
100多节Python课程视频,涵盖必备基础、爬虫和数据分析
100多个Python实战案例,学习不再是只会理论
华为出品独家Python漫画教程,手机也能学习
历年互联网企业Python面试真题,复习时非常方便
请添加图片描述
请添加图片描述

标签:tmp,存储,字节,Python,读写,二进制,PAGE,SIZE
From: https://blog.csdn.net/weixin_45866698/article/details/142105329

相关文章

  • Python 基础学习路线图【有PDF版】
    从遗忘到铭记:我的Python学习之旅曾经,学习对我来说就像一场匆匆的旅行——沿途的风景虽美,但转瞬即逝。除了那些在工作中反复磨练的技能,大多数知识仿佛过客般匆匆离去。尽管日复一日地忙碌着,每当被问及“你究竟学到了什么?”时,脑海中却一片空白。归其原因还是因为学习的内容比较杂乱......
  • 基于python+flask框架的学生成绩管理系统(开题+程序+论文) 计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着教育信息化的不断推进,传统的手工记录与管理学生成绩的方式已难以满足现代教育的需求。传统的成绩管理方式不仅效率低下,易出错,且难以实......
  • 基于python+flask框架的学生信息管理系统设计与实现(开题+程序+论文) 计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着高等教育的普及与信息技术的飞速发展,学生信息管理成为了各大学校日常运营中不可或缺的一部分。传统的人工管理方式不仅效率低下,还容易......
  • 基于python+flask框架的在线新闻发布系统的设计与开发(开题+程序+论文) 计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展,信息传播的速度与广度达到了前所未有的高度。新闻作为社会信息的重要载体,其发布与传播的方式直接影响着公众对时......
  • ColchisFM 新模块发布 | ColchisFM-Python开发接口功能模块
    Python作为目前最流行的一种高级编程语言,‌以其易读性和易用性而闻名。‌特别在人工智能和数学计算上,有着天然的优势和丰富的开源算法库。ColchisFM在地质模型构建方面具有智能化、矢量化、可见即可得的特点。自动化建立地层格架,处理复杂正/逆断层、地层尖灭、地层超覆、削截、......
  • python画图|极坐标中画散点图
    python极坐标画图时,不仅可以画实线图,也可以画散点图。实线图画法如下述链接。python画图|极坐标画图基础教程-CSDN博客今天我们一起学习一下散点图画法。【1】官网教程首先依然是导航到官网,乖乖学习官网教程:Scatterplotonpolaraxis—Matplotlib3.9.2documentatio......
  • Python 中的 super(类名, self).__init__() 的含义
    Questionpytorch中定义的神经网络类的__init__()中,经常定义super(类名,self).__init__(),解释下这句话。比如:classTestNN(nn.Module):#初始化函数def__init__(self,parm1,...): super(TestNN,self).__init__() passAnswer这其实是python中的魔术......
  • python-字符串
    1.在python中,字符串是被定义为在引号(或双引号)之间的一组连续的字符。这个字符可以是键盘上所有可见字符,也可以是不可见的“回车符” “制表符”等。字符串的操作方法很多,这里只选出最典型的几种。(1)字符串大小写转换》S.lower():字母大写转换成小写。》S.upper():字母小写转......
  • 四年前端 自学Python The fifth Day
    1.1定义类类是对象的蓝图或模板,它定义了对象的属性和行为。示例代码:1.2创建对象对象是类的实例,通过类可以创建多个对象。示例代码:1.3类的成员类的成员包括实例变量、类变量、实例方法和类方法。1.4.1实例变量实例变量是与具体对象关联的变量,使用self引用。示......
  • Python 装饰器之__call__()
    已知我们可以用装饰器模式去实现切面功能,啊你不知,那么请看python装饰器模式实现切面功能。除此之外还有其他方式去实现切面功能吗?当然有,那就是python的__call__()方法,call()是一个特殊方法,用于将一个类实例变成一个可调用的对象,即可以像函数一样调用这个类。当调用一个类实例时......