skp*_*skp 0 python gzip mmap python-3.x
我的要求是读取 gzip 压缩文件,由于这些文件很大,我想对其进行内存映射以获得 I/O 性能。
我尝试了以下代码:
import gzip
import mmap
with gzip.open("/home/test.json.gz", mode="r") as f:
with mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_READ) as f_mmap:
print(f_mmap.read())
Run Code Online (Sandbox Code Playgroud)
上面代码中的语句print打印以下一系列十六进制作为输出:
b'\x1f\x8b
Run Code Online (Sandbox Code Playgroud)
当我尝试从上面的代码中删除 时mmap,我看到了正确的预期结果。
您能否提供有关如何内存映射 gzip 压缩文件的建议?
mmap是原始文件访问;它使用的唯一东西f(从创建的对象gzip.open)是.fileno()获取原始文件描述符的方法,它根本不知道文件是否被压缩(gzip.open将原始文件描述符包装在按需执行解压缩的层中,但是低级文件描述符不知道所有这些)。
为了解决一些困惑:mmap不会给你带来神奇的 I/O 性能提升。如果您满足以下条件,它非常有用:
对于像 JSON 这样的东西,随机访问本质上是没有用的;该文件可能是 UTF-8 文本,因此甚至不能保证随机访问落在有效字符的开头,即使是,JSON 中字符 N 的解释也取决于字符 0 到 N 的解释 - 1(我们是在一个对象、数组、字符串等中吗?不知道其余的就无法知道)。所以#1 不适用。
同样,一遍又一遍地重复读取同一个 JSON 文件也没有什么好处;反序列化一次并使用它。
重点是,跳过mmap并执行:
import json
import gzip
with gzip.open("/home/test.json.gz", mode="r") as f:
data = json.load(f)
Run Code Online (Sandbox Code Playgroud)
如果您的文件采用随机访问有意义的格式,您仍然无法直接使用 gzip 压缩文件(压缩数据,如 JSON,是依赖于上下文的;您需要来自先前字节的上下文来解释下一个字节)。如果出于某种原因必须使用mmap,则需要先将其解压,例如:
import gzip
import shutil
import tempfile
with tempfile.TemporaryFile() as f_temp: # Make an unnamed temporary file to use for mmap
with gzip.open("/home/test.data.gz") as f:
shutil.copyfileobj(f, f_temp) # Efficiently decompress from gzip to temp file
f_temp.flush() # Ensure no data stuck in user-mode buffers
# Memory map temporary file and use it
with mmap.mmap(f_temp.fileno(), length=0, access=mmap.ACCESS_READ) as f_mmap:
print(f_mmap.read())
# mapping closed and deleted outside its with
# temporary file closed and deleted outside its with
Run Code Online (Sandbox Code Playgroud)
在实践中,如果您会经常重复使用这个文件,我建议只将其存储为未压缩的,以避免每次使用前都解压缩,但我想我会演示如何使类似的东西工作,以防您真正使用情况需要它。
| 归档时间: |
|
| 查看次数: |
852 次 |
| 最近记录: |