python - 在 Python 2.7 中高效读取 800 GB XML 文件

标签 python xml python-2.7 file io

我正在 python 2.7 中读取一个 800 GB 的 xml 文件并使用 etree 迭代解析器对其进行解析。

目前,我只是使用 open('foo.txt') 没有缓冲参数。我有点困惑这是我应该采用的方法,还是应该使用缓冲参数或使用来自 io 的东西,例如 io.BufferedReader 或 io.open 或 io.TextIOBase。

我们将不胜感激。

最佳答案

标准 open() function默认情况下,已经返回一个缓冲文件(如果在您的平台上可用)。对于通常完全缓冲的文件对象。

通常这里的意思是 Python 把它留给 C stdlib 实现;它使用 fopen() call (wfopen() 在 Windows 上支持 UTF-16 文件名),这意味着选择了文件的默认缓冲;在 Linux 上,我相信这将是 8kb。对于像 XML 解析这样的纯读取操作,这种类型的缓冲正是你想要的。

iterparse 完成的 XML 解析以 16384 字节 (16kb) 的 block 读取文件。

如果要控制缓冲区大小,请使用 buffering关键字参数:

open('foo.xml', buffering=(2<<16) + 8)  # buffer enough for 8 full parser reads

这将覆盖默认缓冲区大小(我希望它匹配文件 block 大小或其倍数)。根据this article增加读取缓冲区应该会有所帮助,并且使用至少 4 倍于预期读取 block 大小加上 8 个字节的大小将提高读取性能。在上面的示例中,我将其设置为 ElementTree 读取大小的 8 倍。

io.open() function表示对象的新 Python 3 I/O 结构,其中 I/O 已被拆分为新的类类型层次结构,以提供更大的灵 active 。代价是更多的间接性,数据必须通过更多的层,Python C 代码自己做更多的工作,而不是把它留给操作系统。

可以试试看io.open('foo.xml', 'rb', buffering=2<<16)会表现得更好。开业时间rb模式会给你一个 io.BufferedReader instance .

你确实想使用io.TextIOWrapper ;底层的 expat 解析器需要原始数据,因为它会自行解码您的 XML 文件编码。它只会增加额外的开销;如果您在 r 中打开,您会得到这种类型(文本模式)。

使用 io.open()可能会给你更多的灵 active 和更丰富的 API,但是底层的 C 文件对象是使用 open() 打开的。而不是 fopen() , 所有缓冲都由 Python io.BufferedIOBase 处理实现。

我认为您的问题将是处理这个野兽,而不是文件读取。无论如何,在读取 800GB 文件时,磁盘缓存几乎都会被拍摄。

关于python - 在 Python 2.7 中高效读取 800 GB XML 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14863224/

相关文章:

python - 将 Python 字典写入 CSV

java - 属性中的 JAX-WS 命名空间,而不是前缀

python - 通过 ElasticSearch DSL python 包装器创建索引时如何在索引级别设置 ignore_malformed?

python - 在 pandas 数据框的分组中获得唯一计数和最大值

python - if 里面的条件

python - BeautifulSoup 误解 <area> 标签

具有属性的Python xmltodict强制数组

c++ - 如何用 Cython 包装 C++ 类?

python - 使用 boto3 从 EFS Amazon 下载文件

android - 从 android 上的 SQLite 数据库填充 ListView