Python 2.7中800gb XML文件的高效读取

2024-05-08 21:53:55 发布

您现在位置:Python中文网/ 问答频道 /正文

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

目前,我只是使用open('foo.txt')而没有缓冲参数。我有点困惑,这是我应该采用的方法,还是应该使用缓冲参数,或者使用io.BufferedReader或io.open或io.TextIOBase中的某些内容。

一个正确的方向将非常感谢。


Tags: 文件方法iotxt解析器内容参数foo
3条回答

你试过偷懒吗?:Lazy Method for Reading Big File in Python?

这似乎已经回答了你的问题。但是,我会考虑使用这种方法将数据写入数据库,mysql是免费的:http://dev.mysql.com/downloads/,NoSQL也是免费的,可能更适合于涉及写入800gb数据或类似数量的操作:http://www.oracle.com/technetwork/database/nosqldb/downloads/default-495311.html

我还没有尝试过使用这种史诗般的xml文件,但上一次我不得不处理大型(相对简单的)xml文件时,我使用了sax parser

它基本上为每个“事件”提供回调,并将其留给您存储所需的数据。你可以给一个打开的文件,这样你就不必一下子把它读进去了。

默认情况下,标准^{} function已经返回缓冲文件(如果您的平台上有)。对于通常完全缓冲的文件对象。

通常这里的意味着Python将此留给C stdlib实现;它在Windows上使用^{} callwfopen()来支持UTF-16文件名),这意味着选择了文件的默认缓冲区;在Linux上,我相信这将是8kb。对于像XML这样的纯读取操作,解析这种类型的缓冲是您所需要的。

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

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

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

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

^{} function表示对象的新的Python 3 I/O结构,在这里,I/O被拆分为新的类类型层次结构,以提供更大的灵活性。代价是更多的间接性,更多的数据必须经过的层,Python C代码本身做更多的工作,而不是把这些留给OS。

你可以试着看看io.open('foo.xml', 'rb', buffering=2<<16)是否会有更好的表现。以rb模式打开将为您提供^{} instance

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

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

你的问题是处理这个野兽,而不是文件读取,我想。当读取一个800GB的文件时,磁盘缓存几乎是快照。

相关问题 更多 >

    热门问题