python - Python mmap.mmap() 到类似字节的对象?
问题描述
的文档mmap
说“内存映射文件对象的行为既bytearray
像文件对象又像文件对象”。
但是,这似乎并没有扩展到标准for
循环:至少对于我目前使用的 Linux 上的 Python 3.8.5,每个mmap.mmap()
迭代器元素都是一个单字节bytes
,而对于 abytearray
和普通文件访问每个元素是一个int
。 更新。更正:对于正常的文件访问,它是可变大小的bytes
;见下文。
这是为什么?更重要的是,我怎样才能有效地从 an 中获取一个类似字节的对象mmap
,所以一个不仅索引而且for
还给我一个的对象int
?(通过有效,我的意思是我想避免额外的复制、强制转换等)
这是演示该行为的代码:
#!/usr/bin/env python3.8
def print_types(desc, x):
for el in setmm: break ### UPDATE: bug here, `setmm` should be `x`, see comments
# `el` is now the first element of `x`
print('%-30s: type is %-30s, first element is %s' % (desc,type(x),type(el)))
try: print('%72s(first element size is %d)' % (' ', len(el)))
except: pass # ignore failure if `el` doesn't support `len()`
setmm = bytearray(b'hoi!')
print_types('bytearray', setmm)
with open('set.mm', 'rb') as f:
print_types('file object', f)
with open('set.mm', 'rb') as f:
setmm = f.read()
print_types('file open().read() result', setmm)
import mmap
with open('set.mm', 'rb') as f:
setmm = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ)
print_types('file mmap.mmap() result', setmm)
这导致
bytearray : type is <class 'bytearray'> , first element type is <class 'int'>
file object : type is <class '_io.BufferedReader'> , first element type is <class 'int'>
file open().read() result : type is <class 'bytes'> , first element type is <class 'int'>
file mmap.mmap() result : type is <class 'mmap.mmap'> , first element type is <class 'bytes'>
(first element size is 1)
更新。修复了furas在评论中指出的错误,结果变为
bytearray : type is <class 'bytearray'> , first element is <class 'int'>
file object : type is <class '_io.BufferedReader'> , first element is <class 'bytes'>
(first element size is 38)
file open().read() result : type is <class 'bytes'> , first element is <class 'int'>
file mmap.mmap() result : type is <class 'mmap.mmap'> , first element is <class 'bytes'>
(first element size is 1)
这回答了会发生什么:由于某种原因,迭代 anmmap
就像迭代文件一样,bytes
每次都返回 a ,但不是像文件那样使用完整的行,而是单字节块。
我的主要问题仍然没有改变:我怎样才能有效地使mmap
行为像字节对象一样(即 indexing 和for
give int
)?
解决方案
我怎样才能有效地让 mmap 表现得像一个字节对象(即,索引和 for give int)?
bytes
是一个在内存中包含数据的对象。但重点mmap
是不要将所有数据加载到内存中。
如果要获取一个bytes
包含文件全部内容的对象,则该文件和整个内容open()
一样正常。read()
使用mmap()
它对自己不利。
也许您想使用memoryview
,它可以由bytes
或构建,mmap()
并且会给您一个统一的 API。
推荐阅读
- mongodb - 使用 mongoose 聚合获取多个字段的计数
- javascript - 使用 .split() 获取包含许多空格的用户名的问题(NodeJS 中的 Discord.js)
- reactjs - React - Redux:如何在从 mapDispatchToProps 分派的函数中获取状态或道具
- php - Stomp-php 在 xampp *http://localhost/dashboard/phpinfo.php* 中不可见
- pickup - 如何知道容器中的代理量(拾取元素)
- javascript - 在 React 的方法中使用状态变量
- python - 我的训练数据集中的隐藏文件使 tensorflow 返回“未知图像文件格式。需要 JPEG、PNG、GIF、BMP 之一。”
- javascript - IE11 中缺少 responseURL
- javascript - 如何使用 python 将数据记录到仪表板应用程序
- javascript - 即使在 XMLHttpRequest (JavaScript/ReactJS) 上切片后上传大文件时浏览器崩溃