Python mmap基础教程

1. 引言

mmap是Python中一种用于操作文件的标准库方法,它可以将一个文件映射至内存,让我们可以通过内存访问文件的内容,进行随机读写操作。这对于文件较大的情况非常有用,比如我们需要读取一个非常大的日志文件,可以无需一次性将整个文件读入内存,而是将需要读取的部分直接映射至内存中,进行读取,不仅能减轻内存负担,还能提高文件的读写速度,从而提高程序的性能。

本篇教程将会详细介绍Python中使用mmap库进行文件操作的方法和步骤,让读者能够通过学习本文,获得使用mmap库处理文件的知识和技巧。

2. mmap基础概念

在介绍mmap库的具体使用前,我们需要先了解一下内存映射文件的基本概念。

mmap,全称为Memory-Mapped Files,即”内存映射文件”,是一种通过将一个文件或设备映射至进程地址空间,让文件或设备可以被看作一片内存来使用的技术。映射后的文件数据存放在虚拟内存中,而不是在真实的内存中,只有在需要访问对应数据时才会被装入真实的内存中。

在Python中,我们可以使用mmap库来实现对文件的内存映射,从而进行文件的读取和写入操作。对于读取较大文件、对文件进行随机读写操作等场景,使用mmap库可以极大地提高读写效率,节省内存空间。

3. mmap库基础用法

3.1 打开文件

要使用mmap库进行文件映射,首先需要打开对应的文件。打开文件的代码示例如下:

import mmap

with open("file.txt", "r") as f:
    # 定位到文件末尾
    f.seek(0, 2)
    # 文件大小(字节数)
    size = f.tell()
    # 回到文件头
    f.seek(0)
    # mmap映射
    mm = mmap.mmap(f.fileno(), size)

其中,open()函数用于打开要操作的文件,以只读方式打开文件时,第二个参数需要传入”r”,以读写方式打开文件时,传入”w”。调用fileno()方法可以获得文件的文件描述符,然后调用mmap()函数进行映射。映射成功后,可以通过mm[index]mm[start:end]来访问文件中对应的数据。

3.2 读取文件

在文件映射成功后,可以通过mm[:]或每次只映射一部分文件再进行读取,来访问文件的内容。

下面是读取整个文件的示例代码:

import mmap

with open("file.txt", "r") as f:
    # 定位到文件末尾
    f.seek(0, 2)
    # 文件大小(字节数)
    size = f.tell()
    # 回到文件头
    f.seek(0)
    # mmap映射
    mm = mmap.mmap(f.fileno(), size)

    # 读取整个文件
    print(mm[:])

    # 关闭映射和文件
    mm.close()

在上面的示例代码中,我们先打开文件并将文件映射至内存中,然后使用mm[:]来读取整个文件,最后关闭映射和文件。

下面是每次只映射一部分文件再读取的示例代码:

import mmap

with open("file.txt", "r") as f:
    while True:
        # 一次读取100字节
        l = f.read(100)
        if not l:
            break
        # 映射
        mm = mmap.mmap(f.fileno(), 100, access=mmap.ACCESS_READ)
        print(mm[:])
        mm.close()

在上面的示例代码中,我们使用了read()函数每次读取100字节,并对每次读取的数据进行映射和读取。由于每次只映射一部分文件,因此在处理大文件时,可以用这种方法来分批处理。

3.3 写入文件

在文件映射成功后,我们还可以直接修改内存中的数据,并将其写入文件中。

下面是写入文件的示例代码:

import mmap

with open("file.txt", "r+") as f:
    # 定位到文件末尾
    f.seek(0, 2)
    # 文件大小(字节数)
    size = f.tell()
    # 回到文件头
    f.seek(0)
    # mmap映射
    mm = mmap.mmap(f.fileno(), size)
    # 修改文件内容
    mm[0:5] = b"ABCDE"
    # 将修改写入文件
    mm.flush()
    # 关闭映射和文件
    mm.close()

在上面的示例代码中,我们首先将文件映射至内存中,然后使用mm[start:end]来修改内存中的数据。在写入完成后,使用mm.flush()将修改写入文件,最后关闭映射和文件。

4. mmap库的进阶用法

4.1 修改文件权限

在使用mmap库进行文件操作时,可能会出现文件权限不足的情况,此时需要修改文件的权限。可以使用os.chmod()函数来修改文件的权限。

示例代码如下:

import os
import mmap

# 修改文件权限
os.chmod("file.txt", 0o777)

with open("file.txt", "r+") as f:
    # 定位到文件末尾
    f.seek(0, 2)
    # 文件大小(字节数)
    size = f.tell()
    # 回到文件头
    f.seek(0)
    # mmap映射
    mm = mmap.mmap(f.fileno(), size)
    # 修改文件内容
    mm[0:5] = b"ABCDE"
    # 将修改写入文件
    mm.flush()
    # 关闭映射和文件
    mm.close()

在上面的示例代码中,我们使用os.chmod()函数修改了文件的权限,然后用mmap库对文件进行了修改。

4.2 非阻塞映射

在进行文件映射时,有时候会出现访问文件锁定的情况,进而导致程序阻塞。为了避免文件映射的阻塞,可以使用mmap.MAP_NORESERVE标志位来进行非阻塞映射。

示例代码如下:

import mmap

with open("file.txt", "r+") as f:
    # 定位到文件末尾
    f.seek(0, 2)
    # 文件大小(字节数)
    size = f.tell()
    # 回到文件头
    f.seek(0)
    # mmap映射
    mm = mmap.mmap(f.fileno(), size, flags=mmap.MAP_SHARED | mmap.MAP_NORESERVE)
    # 修改文件内容
    mm[0:5] = b"ABCDE"
    # 将修改写入文件
    mm.flush()
    # 关闭映射和文件
    mm.close()

在上面的示例代码中,我们使用mmap.MAP_NORESERVE标志位进行了非阻塞映射,避免了文件锁定导致的阻塞现象。

4.3 虚拟内存控制

虚拟内存控制是指在进行文件映射后,通过控制虚拟内存来控制文件的读写权限和映射方式。可以使用mmap.PROT_READ/mmap.PROT_WRITE/mmap.PROT_EXEC/mmap.PROT_NONE标志位来设置页面的权限。

示例代码如下:

import mmap

with open("file.txt", "r+") as f:
    # 定位到文件末尾
    f.seek(0, 2)
    # 文件大小(字节数)
    size = f.tell()
    # 回到文件头
    f.seek(0)
    # mmap映射
    mm = mmap.mmap(f.fileno(), size, prot=mmap.PROT_READ)
    # 修改文件内容
    mm[0:5] = b"ABCDE"
    # 将修改写入文件
    mm.flush()
    # 关闭映射和文件
    mm.close()

在上面的示例代码中,我们使用mmap.PROT_READ标志位设置了页面的权限为只读,从而避免了对文件的篡改和误操作。

5. 总结

本文介绍了Python中使用mmap库进行文件操作的基本知识和技巧。mmap库不仅能够提高程序读写文件的效率,还能节省内存空间,因此在处理大文件时非常有用。在使用mmap库进行文件操作时,需要注意权限、阻塞、虚拟内存控制等问题,避免出现程序错误和不安全情况。

原创文章,作者:TTYW,如若转载,请注明出处:https://www.506064.com/n/143096.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
TTYWTTYW
上一篇 2024-10-14 18:45
下一篇 2024-10-14 18:45

相关推荐

  • Python周杰伦代码用法介绍

    本文将从多个方面对Python周杰伦代码进行详细的阐述。 一、代码介绍 from urllib.request import urlopen from bs4 import Bea…

    编程 2025-04-29
  • Python计算阳历日期对应周几

    本文介绍如何通过Python计算任意阳历日期对应周几。 一、获取日期 获取日期可以通过Python内置的模块datetime实现,示例代码如下: from datetime imp…

    编程 2025-04-29
  • 如何查看Anaconda中Python路径

    对Anaconda中Python路径即conda环境的查看进行详细的阐述。 一、使用命令行查看 1、在Windows系统中,可以使用命令提示符(cmd)或者Anaconda Pro…

    编程 2025-04-29
  • Python中引入上一级目录中函数

    Python中经常需要调用其他文件夹中的模块或函数,其中一个常见的操作是引入上一级目录中的函数。在此,我们将从多个角度详细解释如何在Python中引入上一级目录的函数。 一、加入环…

    编程 2025-04-29
  • Python列表中负数的个数

    Python列表是一个有序的集合,可以存储多个不同类型的元素。而负数是指小于0的整数。在Python列表中,我们想要找到负数的个数,可以通过以下几个方面进行实现。 一、使用循环遍历…

    编程 2025-04-29
  • Python清华镜像下载

    Python清华镜像是一个高质量的Python开发资源镜像站,提供了Python及其相关的开发工具、框架和文档的下载服务。本文将从以下几个方面对Python清华镜像下载进行详细的阐…

    编程 2025-04-29
  • 蝴蝶优化算法Python版

    蝴蝶优化算法是一种基于仿生学的优化算法,模仿自然界中的蝴蝶进行搜索。它可以应用于多个领域的优化问题,包括数学优化、工程问题、机器学习等。本文将从多个方面对蝴蝶优化算法Python版…

    编程 2025-04-29
  • Python字典去重复工具

    使用Python语言编写字典去重复工具,可帮助用户快速去重复。 一、字典去重复工具的需求 在使用Python编写程序时,我们经常需要处理数据文件,其中包含了大量的重复数据。为了方便…

    编程 2025-04-29
  • Python程序需要编译才能执行

    Python 被广泛应用于数据分析、人工智能、科学计算等领域,它的灵活性和简单易学的性质使得越来越多的人喜欢使用 Python 进行编程。然而,在 Python 中程序执行的方式不…

    编程 2025-04-29
  • python强行终止程序快捷键

    本文将从多个方面对python强行终止程序快捷键进行详细阐述,并提供相应代码示例。 一、Ctrl+C快捷键 Ctrl+C快捷键是在终端中经常用来强行终止运行的程序。当你在终端中运行…

    编程 2025-04-29

发表回复

登录后才能评论