前言:
而今朋友们对“python修改文件数据”大致比较关注,姐妹们都想要分析一些“python修改文件数据”的相关资讯。那么小编也在网络上网罗了一些对于“python修改文件数据””的相关内容,希望我们能喜欢,小伙伴们快快来了解一下吧!首先科普一下,什么叫映射?在计算机程序中,映射(mapping)是一种将一个数据集合中的每个元素(称为“键”)都对应到另一个集合中的唯一元素(称为“值”)的方法。简单理解数组就是映射的一种形式。
那显而易见什么是文件映射,就是将磁盘上的文件的位置,与进程逻辑地址空间中一块大小相同的区域之间的一一对应。映射后得到一个类似数组类型的东西(mmap.mmap()对象),可以通过类似操作数组的方式,达到对文件内容更改的目的。
文件映射到内存的作用:
了解什么是文件映射之后,我们就要思考一下文件映射有什么作用,如下:
1、二进制文件便捷读写
读写二进制文件还在使用open函数?各种组合seek()、read()和write()累不累?尤其二进制文件操作,非常不方便。
二进制文件数据写入文件时是以数组的形式。将数据映射到文件内,然后就以访问数组的形式访问文件,而且在对文件进行修改后,能再次通过此数组将数据同步到文件中。
2、可以提高文件读写效率,避免频繁的进行文件I/O操作
在某些情况下,我们需要处理大文件,例如日志文件、数据库文件等,使用传统的文件读写方式可能会遇到性能问题。为了提高文件处理的效率,我们可以将文件映射到内存中,从而可以直接对内存中的数据进行操作,而不需要频繁地进行磁盘读写操作。
3、某些嵌入式设备,寄存器被编址到内存地址空间,比如/dev/mem,我们可以映射这个文件来访问这些寄存器
如何访问嵌入式设备的寄存器呢?实际上,寄存器就是物理地址的某一特定空间;此时,如果要访问寄存器,只需要将 /dev/mem 的某一范围映射到内存中,用访问内存的方式来访问寄存器;
4、如果多个进程映射同一个文件,还能实现进程通信的目的
多个进程把同一个文件映射到各自的内存空间当中,实际上它们看到的是同一个视图,这样也能实现进程通信的目的。
在python中,如何将文件映射到内存?
使用标准库中mmap模块下的mmap()函数,它需要一个打开的文件描述符作为参数。
# windows版本mmap.mmap(fileno, length, tagname=None, access=ACCESS_DEFAULT, offset=0)# Unix 版本mmap.mmap(fileno, length, flags=MAP_SHARED, prot=PROT_WRITE | PROT_READ, access=ACCESS_DEFAULT, offset=0, *, trackfd=True)
fileno:文件描述符;length:映射区域的大小,必须以页(mmap.PAGSIZE)为单位,0表示全部;offset:指定映射文件的某一区域,相当于文件指针,指定的区域必须是页(mmap.PAGESIZE)的整数倍;flags:指明映射的性质。 MAP_PRIVATE 会创建私有的写入时拷贝映射,因此对 mmap 对象内容的修改将为该进程所私有。 而 MAP_SHARED 会创建与其他映射同一文件区域的进程所共享的映射。 默认值为 MAP_SHARED。prot:如果指明了 prot,它将给出所需的内存保护方式;最有用的两个值是 PROT_READ 和 PROT_WRITE,分别指明页面为可读或可写。 prot 默认为 PROT_READ | PROT_WRITE。access:ACCESS_READ , ACCESS_WRITE 或 ACCESS_COPY 分别指定只读,直写或写时复制内存,可以指定 access 作为替代 flags 和 prot 的可选关键字形参。 同时指定 flags, prot 和 access 将导致错误。trackfd:如果 trackfd 为 False,则由 fileno 指定的文件描述符将不会被复制,而结果 mmap 对象将不会被关联到映射的下层文件。 这意味着 size() 和 resize() 方法将会失败。 此模式适用于限制打开文件描述符的数量。
import mmap# write a simple example filewith open("hello.txt", "wb") as f: f.write(b"Hello Python!\n")with open("hello.txt", "r+b") as f: # memory-map the file, size 0 means whole file mm = mmap.mmap(f.fileno(), 0) # read content via standard file methods print(mm.readline()) # prints b"Hello Python!\n" # read content via slice notation print(mm[:5]) # prints b"Hello" # update content using slice notation; # note that new content must have same size mm[6:] = b" world!\n" # ... and read again using standard file methods mm.seek(0) print(mm.readline()) # prints b"Hello world!\n" # close the map mm.close()
mmap内存映射原理
mmap内存映射的实现过程,总的来说可以分为三个阶段:
进程启动映射过程,并在虚拟地址空间中为映射创建虚拟映射区域;调用内核空间的系统调用函数mmap,实现文件物理地址和进程虚拟地址的映射关系进程发起对这片映射空间的访问,引发缺页异常,实现文件内容到物理内存(主存)的拷贝mmap在不同操作系统中的差异
在不同的操作系统中,mmap模块的表现可能会有所不同。这里给一个官方文档的参考:mmap --- 内存映射文件支持 Python 3.13.0rc2 文档
1、文件大小
在 Windows 系统中,通过 mmap 模块创建内存映射文件时,文件大小有限制(通常是 2GB)。而在 Linux 系统中,这个限制要高得多。
2、文件模式
在 Windows 系统中,使用 mmap 时,文件必须以二进制模式打开。在 Linux 系统中,文件可以以文本模式或二进制模式打开。
3、内存映射的保护和访问模式
在 Windows 系统中,mmap 模块的 access 参数不支持 mmap.ACCESS_COPY。而在 Linux 系统中,这个参数是支持的。
4、解除内存映射
在 Windows 系统中,解除内存映射需要调用 m.close() 方法,然后调用 f.close()。在 Linux 系统中,只需调用 m.close() 即可。
5、文件偏移量
在 Windows 系统中,如果文件的大小小于创建内存映射区的大小,那么文件的实际大小将会增加到创建内存映射区的大小。在 Linux 系统中,文件的大小不会因创建内存映射区的大小而改变。
标签: #python修改文件数据