【问题标题】:Opening memory-mapped file with encoding使用编码打开内存映射文件
【发布时间】:2016-03-25 23:29:07
【问题描述】:

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'

创建包装器(使用继承)并将方法 seekablereadablewritable 设置为返回 True 也不起作用。

关于编码,可能会采用固定长度编码,如utf-32、代码点或utf-16 的较低 BMP(如果甚至可能仅指该部分)。

欢迎任何 python 版本的解决方案。

【问题讨论】:

  • 对于像 UTF-8 这样的可变长度编码,如果不通过之前的 49999 个字符,就无法判断字符 50000 在哪里,这违背了内存映射的目的。你可能会发现一些适用于固定长度编码的东西。
  • @user2357112 认为这可能会造成问题,但为了这个问题,可能会假设固定长度,如utf-16utf-32 或代码点。
  • UTF-16 仍然是可变长度的,无论如何,问题在于文件的编码,而不是模式的编码。
  • @user2357112 更新为指定utf-32utf-16 的较低BMP,如果它甚至可能仅指该部分。是的,文件的编码确实是问题。

标签: python python-2.7 python-3.x encoding memory-mapped-files


【解决方案1】:

如果不从头开始重新发明轮子(编写 re 模块、mmap 模块的所有新版本等),或者编写无法使用细节的非常复杂的正则表达式,您就无法做到这一点诸如真正的 Unicode 字符范围之类的东西(您可以在三种不同的模式之间进行交替以生成 [\u1234-\u5678],类似于 (?:\x12[\x34-\xff]|[\x13-\x55].|\x56[\x00-\x78]))。

基本上,re 模式仅适用于 str,或适用于类似 bytes 的对象(您不能尝试使用 memoryviews 和强制转换来解决它,因为 re 仍然处理它是字节,而不是更大的类型)。

对于简单的搜索,您可以尝试在对用于搜索的字符串进行编码后使用mmap.find,但这仍然容易出现细微的错误;对于 UCS-2 或 UTF-32,您需要检查来自 find 的返回值是否分别在两个或四个字节边界上对齐,以确保您没有弄错一个字符的结尾和开头接下来是一个完全不同的角色。如果对齐测试失败,您必须使用最后一个返回值的 start 偏移量 + 1 重复搜索,直到您获得命中或 find 返回 -1。在一般情况下,这不是一件合理的事情。

【讨论】:

  • 正则表达式应该是(?:\x12[\x34-\xff]|[\x13-\x55].)|(?:\x56[\x00-\x78]) btw。
  • @Bharel:你给出的那个模式相当于[\u1234-\u55ff][\u5600-\u5678],不是吗?针对不同范围的两个不同类别,而不是一个涵盖整个范围的类别。当然,它仍然只有在数据是大端 UCS-2 的情况下才有效;如果它是小端,你必须翻转每个交替的内容。
  • 我的错,还是一样。我也忘记了字节序。真是一团糟。无论如何,如果你对它不存在的事实是正确的,这听起来相当不幸,但我会等待另一个答案。我相信我不是第一个想到在文本文件上使用 mmap 的人(或者至少我希望我不是)。如果在合理的时间内没有出现,我会接受这个答案是我的命运。
  • @Bharel:你不是第一个想到它的人,因为我知道几年前我试图弄清楚这是否可能。 :-) 我尝试了很多方法,但 mmaps 不能做多字节,memoryviews,甚至 cast 到不同的大小,仍然像 bytesre bytes 模式, 和 re str 模式仅适用于 str(和 Py2 上的 unicode),而不是任意类型。
  • 那么,我想我们都注定要失败 :-( 也许您应该联系您在 Microsoft 的朋友为我们提供一个用于编码 mmap 的智能 WinAPI :P 我仍然会耐心等待奇迹般的答案我猜。
猜你喜欢
  • 2013-02-17
  • 2018-05-18
  • 2016-02-23
  • 1970-01-01
  • 2015-02-16
  • 1970-01-01
  • 2013-07-16
  • 1970-01-01
  • 2011-12-31
相关资源
最近更新 更多