zoukankan      html  css  js  c++  java
  • 使用mmap映射后,文件中的'\n'变成了'\r\n'

      关于mmap,《Python v2.7.2 documentation》中的描述如下:

    mmap — Memory-mapped file support

      Memory-mapped file objects behave like both strings and like file objects. Unlike normal string objects, however, these are mutable. You can use mmap objects in most places where strings are expected; for example, you can use the re module to search through a memory-mapped file. Since they’re mutable, you can change a single character by doing obj[index] = 'a', or change a substring by assigning to a slice: obj[i1:i2] = '...'. You can also read and write data starting at the current file position, and seek() through the file to different positions.

      在re+mmap实现大文件的正则匹配中,我采取“首先用mmap映射文件,然后用re匹配内容”的方法进行过大文件的正则匹配。这种方法确实有效。但是,当我将使用正则表达式从映射文件中提取到的匹配结果写入新文件时,用Vim打开新文件后,每一行的结尾处总有一个^M字符(0x0d)。当时觉得有点奇怪,不过想了想又以为可能是正则匹配的中间信息没有被删除掉,当时也不影响后续的文件操作,所以也没有继续研究。

      最近因为要分析C程序中的宏的缘故,再次用到了re+mmap组合。待分析的头文件data.h的内容为:

     #define LEN 2\n

      按照逻辑,我编写了如下正则表达式用于匹配提取宏名及其对应的替换文本

    macro_regex = re.compile(r"\s*#\s*define\s*(\w+)\s*(.*?)[\n]")

      以下代码中,分别使用macro_regex直接匹配文件内容,以及匹配mmap映射后的文件内容

    f = open('data.h', 'r')
    
    # 直接匹配文件内容
    data = f.read()
    print macro_regex.findall(data)
    
    # 匹配mmap映射后的文件内容
    data = mmap.mmap(f.fileno(), 0, access = mmap.ACCESS_READ)
    print macro_regex.findall(data)
    
    f.close()
    

      所得的结果输出为:

    [('LEN', '2')]
    [('LEN', '2\r')]
    

      上述结果表明:mmap映射后的文件内容发生了变化。于是,我又直接比较了data.h的原始文件内容和mmap映射后的文件内容:

    #define LEN 2\n      ## 原始文件内容

    #define LEN 2\r\n   ## mmap映射后的文件内容

      果然,mmap映射后的文件内容中,原来的'\n'变成了'\r\n'。我这才发现,原来之前Vim打开时看到的每行末尾的^M字符(0x0d)其实就是'\r'。我后来又做了一系列的测试(比如将mmap映射后的文件内容直接写入到另一个文件中),证实了确实存在这种差异。

    “  使用mmap映射后,文件中的'\n'变成了'\r\n'  ”

      这种差异非常隐晦,一般情况下很难预料;但这种差异的影响却显而易见:如果使用mmap映射后的文件内容已经发生了变化,那么以原始的文件内容为依据的所有假设和逻辑都可能会出现混乱。

      值得一提的是,这种情况是我在Windows下面使用Python2.7时遇到的,其他系统平台和Python版本下的情况我没有验证过。在此做一个记录,以备后续回顾与参考。


  • 相关阅读:
    [windbg] 进程、线程
    [Windows 驱动开发] 驱动中获取函数地址
    [DuiLib] 入坑资料收集
    [Windows 驱动开发] 获取驱动详细信息
    基于模板的SPS展示层定制
    关于工作角色的一个新的思考
    中小企业IT建设的有关思路
    定制SharePoint Portal之去除帮助链接
    大客户谈判技巧关于IT行业售前工作
    细节决定成败
  • 原文地址:https://www.cnblogs.com/russellluo/p/2241840.html
Copyright © 2011-2022 走看看