Python中mmap文件映射
为什么要使用 mmap 这个内存映射呢? 这是因为人们觉得用它来处理文件的时候会更好。想要去随机访问到那个文件里面所存放的内容的话, 选择把那些文件给映射到这个内存里去, 那么使用这个mmap这个方法, 它就是一个既高效, 又显得非常优雅的一个方法。比如说吧, 我们不需要去打开一个具体的文件, 然后去执行那些大量的关于seek()、read()以及write()的调用动作了, 只需要简单地把这个文件映射上去, 然后再直接使用切片操作的方法去访问里面的数据, 这就完全可以做到这一点。当内存映射一个文件的时候, 这并不会导致该文件被读取到内存里面, 所以, 说法是, 文件并没有被复制到内存缓存或者说数组里面去的, 反之, 操作系统只是为文件内容保留了一段虚拟内存存在那里的, 在访问文件的不同区域的过程中, 这些不同区域的内容, 才是按需被读取然后被映射到内存区域里面的, 而那些从来都没被访问到的部分的话, 它们依旧还留在磁盘上的位置呢, 所有这些流程都是透明的, 而且都是在幕后被完成的。mmap介绍mmap是那种通过虚拟内存技术把文件给映射进来的一个手段, 它能把一个文件, 或者是一些其他的对象, 直接弄到进程的地址空间里面去, 这样一来的话, 就能实现文件里面的磁盘地址, 还有进程虚拟地址空间那一块特定的虚拟地址之间, 能够形成一种一一对应的紧密关系了。*mmap 模块提供“内存映射的文件对象”mmap 对象可以用在使用 plain 的地方mmap 对象和 plain 的区别是mmap使用细节1、在使用mmap这个方法的时候, 大家需要特别当心一个比较关键的点, 这个点就是说, 你用mmap搞出来的那个映射区域的大小, 必须得是那个物理页的大小的整倍数, 在32位的那种系统里面, 这个大小通常就是4k字节, 为什么, 因为内存这个东西它操作的最小单位就是页, 然后进程里面的虚拟地址空间和实际的内存做映射这件事儿, 它也是以页作为一个单位的, 所以为了能够跟对内存本身的操作方式匹配起来, mmap要把数据从磁盘弄到那个虚拟地址空间上去的这个过程, 它的映射也必须是要以页为单位的。2、内核可以跟踪被内存映射的底层的对象文件的大小, 进程可以合法的访问在当前文件大小以内, 又在内存映射区以内的那些字节。也就是说, 如果文件的大小一直在扩张, 只要在映射区域范围内的数据, 进程都可以合法得到。这和映射建立时文件的大小无关。具体的情形可以参考“情形三”。3、在映射建立好之后, 哪怕文件被关闭了, 这个映射还是照样存在的。这是因为我们映射的是磁盘上的地址空间, 而不是文件本身, 所以它和文件句柄完全没有关系。另外, 因为采用的是按页进行映射的方式, 所以进程间能够共享用于通信的有效地址空间, 并不会完全只受限于被 的那个文件原本的大小。创建mmap对象mmmap.mmap(fileno, length[, flags[, prot[, access[, offset]]]])参数功能文件描述符, 这个值你可以把它看作是 file 对象的那个特定方法的执行结果, 或者它是通过 os.open() 函数拿到的东西, 在你去调用 mmap() 这个操作之前肯定得先把这个文件给顺利打开, 而等到你后面不再需要占用这个文件资源的关键时刻你必须要把它正确地关闭起来。你需要去映射出文件部分的大小这里的单位是字节。如果这个值等于零的话, 那么就会去映射整个文件。要是这个大小大于了文件当前的大小, 就会去扩展这个文件。。flags这段内存映射只能够被当前所在的这个进程自己所使用, 而mmap这一种方式则是用来将内存映射的内容和其他的进程共同分享的, 因此所有那些已经映射在了同一个文件之上的进程, 都完全有能力看清楚并获取到由其中任意一个进程中所做出的更改内容。protmmap.、mmap.、和mmap. 、以及 mmmpp.. 这最后一种情况, 它的含义就是数据既能够被读取, 又能够被写入, 也就是说它是同时进行可读与可写操作的。在mmap函数里面, 存在可选参数, 这些可选参数的值包括读访问这种方式, 还有写访问这种方式, 其中的写访问是默认的状态, 此外还存在拷贝访问这种方式, 拷贝访问的特点是不会把修改的内容直接写入到文件之中, 需要调用flush这个操作才能够把更改的部分写入到文件里。关于mmap对象所包含的那些函数。函数功能close()把那个和 m 对应的文件关掉。m.查找字符串, 起始位置默认为零。从start这个下标位置开始出发, 在字符串m当中从左到右进行寻找, 目标是找到子串str最早现身的那个下标的地方。m.flush(, n需要把m里面从最开头的那个地方数出来, 数到第n个字节这么长的这一串东西, 把它给写进去或者说是刷到那个对应的文件里面去。m.move(, , n)等于 m:n m:n把从 开始的 n 个字节复制到从 开始的n个字节可能会覆盖重叠的部分m.现在进行读取操作。返回一个字符串, 从由m对应的文件之中最多读取n个字节, 将会把m所对应文件的位置指针向后移动。m.()该函数会返回一个长度为一字节的字符串, 它负责从指定名称为m的文件里面读取一个字节的数据内容。如果当前的代码执行位置已经到达文件末尾标志的位置也就是所谓的eof状态下, 仍然继续调用这个特定的函数操作的话, 系统就会强制抛出相应的异常错误提示。m.()返回一个字符串, 这个字符串的内容是从 m 所对应的文件的当前位置开始, 一直到遇到的下一个换行符结束, 其中换行符的表示方式是用单引号圈起来的反斜杠和 n 组成的 ’\n’, 当调用该函数的过程中如果发现文件已经处于末尾位置了, 也就是所谓的 EOF 状态的时候, 就会返回一个空字符串。m.seek(pos, how0)与 file 对象具备的 seek 操作类似, 该行为会对 m 所关联的文件执行调整其内部当前位置的操作。m.size()返回那个与 m 相互对应的文件的总长度, 这里要注意所指的并不是那个名为 m 的对象的长度, 也就是不是 len(m) 这种意义上的长度。m.tell()