2024-05-08 21:53:55 发布
网友
我正在python 2.7中读取一个800gb的xml文件,并使用etree迭代解析器对其进行解析。
目前,我只是使用open('foo.txt')而没有缓冲参数。我有点困惑,这是我应该采用的方法,还是应该使用缓冲参数,或者使用io.BufferedReader或io.open或io.TextIOBase中的某些内容。
open('foo.txt')
一个正确的方向将非常感谢。
你试过偷懒吗?: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上使用^{} call(wfopen()来支持UTF-16文件名),这意味着选择了文件的默认缓冲区;在Linux上,我相信这将是8kb。对于像XML这样的纯读取操作,解析这种类型的缓冲是您所需要的。
wfopen()
由iterparse完成的XML解析以16384字节(16kb)的块读取文件。
iterparse
如果要控制缓冲区大小,请使用buffering关键字参数:
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.open('foo.xml', 'rb', buffering=2<<16)
rb
您确实不想使用io.TextIOWrapper;底层expat解析器需要原始数据,因为它将对XML文件编码本身进行解码。它只会增加额外的开销;如果改为在r(textmode)中打开,则会得到这种类型。
io.TextIOWrapper
r
使用io.open()可能会给您更大的灵活性和更丰富的API,但是底层的C文件对象是使用open()而不是fopen()打开的,所有缓冲都由Python io.BufferedIOBase实现处理。
io.open()
open()
fopen()
io.BufferedIOBase
你的问题是处理这个野兽,而不是文件读取,我想。当读取一个800GB的文件时,磁盘缓存几乎是快照。
你试过偷懒吗?: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上使用^{} call (
wfopen()
来支持UTF-16文件名),这意味着选择了文件的默认缓冲区;在Linux上,我相信这将是8kb。对于像XML这样的纯读取操作,解析这种类型的缓冲是您所需要的。由
iterparse
完成的XML解析以16384字节(16kb)的块读取文件。如果要控制缓冲区大小,请使用
buffering
关键字参数:它将覆盖默认缓冲区大小(我希望它与文件块大小或其倍数匹配)。根据this article的说法,增加读缓冲区应该有帮助,并且使用至少是预期读块大小的4倍加上8字节的大小将提高读性能。在上面的示例中,我将其设置为ElementTree读取大小的8倍。
^{} function 表示对象的新的Python 3 I/O结构,在这里,I/O被拆分为新的类类型层次结构,以提供更大的灵活性。代价是更多的间接性,更多的数据必须经过的层,Python C代码本身做更多的工作,而不是把这些留给OS。
你可以试着看看} instance 。
io.open('foo.xml', 'rb', buffering=2<<16)
是否会有更好的表现。以rb
模式打开将为您提供^{您确实不想使用
io.TextIOWrapper
;底层expat解析器需要原始数据,因为它将对XML文件编码本身进行解码。它只会增加额外的开销;如果改为在r
(textmode)中打开,则会得到这种类型。使用
io.open()
可能会给您更大的灵活性和更丰富的API,但是底层的C文件对象是使用open()
而不是fopen()
打开的,所有缓冲都由Pythonio.BufferedIOBase
实现处理。你的问题是处理这个野兽,而不是文件读取,我想。当读取一个800GB的文件时,磁盘缓存几乎是快照。
相关问题 更多 >
编程相关推荐