Memory mapped file是使用正则表达式或对大型二进制文件进行操作的有效方法。
如果我有一个大文本文件 (~1GB),是否可以使用编码感知映射文件?
[\u1234-\u5678]
之类的正则表达式不适用于 bytes
对象,将模式转换为 unicode 也不起作用(如 [\u1234-\u5678]".encode("utf-32")
例如将无法正确理解范围)。
如果我使用 .encode()
将搜索模式从 str
转换为 bytes
,搜索可能会起作用,但它仍然有些受限,应该有一个更简单的方式而不是整天解码和编码。
我尝试用 io.TextIOWrapper
将其包装在 io.BufferedRandom
中,但无济于事:
AttributeError: 'mmap.mmap' object has no attribute 'seekable'
创建包装器(使用继承)并设置方法 seekable
、readable
和 writable
以返回 True
也没有用。
关于编码,固定长度的编码,如 utf-32
,代码点或 utf-16
的较低 BMP(如果它甚至可能仅指那部分) 可以假设。
欢迎使用任何 python 版本的解决方案。
最佳答案
如果不从头开始重新发明轮子(编写所有新版本的 re
模块、mmap
模块等),或者编写非常复杂的正则表达式,不能使用诸如真正的 Unicode 字符范围之类的东西的优点(你可以在三种不同的模式之间进行交替来制作 [\u1234-\u5678]
,比如 (?:\x12[\x34-\xff]|[\x13-\x55].|\x56[\x00-\x78])
).
基本上,re
模式仅适用于 str
,或适用于类似 bytes
的对象(并且您不能尝试变通它与 memoryview
和转换,因为 re
仍然将其视为字节,而不是更大的类型)。
对于简单的搜索,您可以尝试使用 mmap.find
在对用于搜索的字符串进行编码之后,但这仍然容易出现细微的错误;对于 UCS-2 或 UTF-32,您需要检查 find
的返回值是否分别在两个或四个字节的边界上对齐,以确保您没有弄错一个字符的结尾和下一个完全不同的角色的开始。如果对齐测试失败,则必须使用上次返回值的 start
偏移量 + 1 重复搜索,直到找到匹配项或 find
返回 -1
。在一般情况下,这不是一件合理的事情。
关于python - 使用编码打开内存映射文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36229717/