如何处理来自python的超大(4Gb)目标文件?

我试图用内部的塔犬很大
Python,并且正在陷入内存约束. tarfile In
问题是freeb.org,http://ftp.freedb.org/pub/freedb/的4 ggabyte datafile,约有250万成员
在里面.
这是一个简单的玩具程序,刚刚完成并计算
TARFILE中的成员数量,打印一个状态消息,每个n
记录(较小文件的n = 10,000;较大的n = 100,000).
我发现记忆使用量通过屋顶,只是迭代
在tarfile上.我几乎一半的时间都在使用超过2G
文件.这让我感到惊讶.我希望与
每次迭代要在迭代结束时发布;但
有些东西显然正在建立.
在一个系统上,这以MemoryError异常结束.另外一个
系统,它只是悬挂,使系统屈膝,
进行简单的任务切换需要一分钟左右的时间.
有什么建议来处理这只野兽吗?我想我可以开除
该文件和处理250万个单独的文件,但我正在考虑
如果可能的话,我宁愿直接处理它.
这是玩具代码. (关于"导入tarfilex作为
tarfile"语句.我正在运行ActiveState Python 2.5.0,
tarfile.py的老式模块是越来越大的,以至于
根本无法读取这些文件.我放下了最近的
tarfile.py来自http://svn.python.org/view/python/trunk/lib/tarfile.py.py
并将其保存为Tarfilex.py.它有效,至少直到我开始
无论如何,处理一些非常大的文件.)
导入Tarfilex作为Tarfile
导入操作系统,时间
sourcedir =" f:/installs/freeb/"
smallfile =" freeb-update-20080601-20080708.tar"#63M文件
SmallInt = 10000
bigfile =" freeb-complete-20080708.tar"#4,329m文件
bigitnt = 100000
tarfileName,间隔=小file,smallint
#TarfileName,Interval = bigfile,bigint
Def Filetype(文件名):
返回os.path.splitext(文件名)[1]
DEF MESUSAGE(单位=" M"):
导入Win32程序
current_process = win32process.getCurrentProcess()
memory_info = win32process.getProcessMemoryInfo(current_process)
字节= 1
kbytes = 1024*字节
mbytes = 1024*kbytes
gbytes = 1024*mbytes
unitfactors = {'b':1,'k':kbytes,'m':mbytes,'g':gbytes}
return memory_info [" workingSetsize"] // unitFactors [单位]
DEF OPENTAR(文件名):
模式= {" .tar":" r"," .gz":" r:gz"," .bz2":" r:bz2"}
OpenMode =模式[FILETYPE(FILENAME)]
openedfile = tarfile.open(文件名,openmode)
返回开放file
tfpath = sourcedir+'/'+tarfileName
OSERT OS.PATH.EXISTS(TFPATH)
astert tarfile.is_tarfile(tfpath)
TF = Opentar(TFPath)
计数= 0
打印"%s内存:%sm计数:%s(stater)"%(time.asctime(),
惊奇(),计数)
对于TF中的Tarinfo:
计数 += 1
如果count%间隔== 0:
打印"%s内存:%sm计数:%s"%(time.asctime(),,,
惊奇(),计数)
打印"%s内存:%sm计数:%s(已完成)"%(time.asctime(),
惊奇(),计数)
结果较小(63m)文件:
星期四7月17日00:18:21 2008年备忘录 Y:4M计数:0(开始)
2008年7月17日00:18:23记忆:18m计数:10000
约7月17日00:18:26 2008记忆:32m计数:20000
2008年7月17日00:18:28记忆:46m计数:30000
2008年7月17日00:18:30记忆:55m计数:36128(完成)
结果较大(4.3G)文件:
2008年7月17日00:18:47记忆:4M计数:0(开始)
约7月17日00:19:40 2008记忆:146m计数:100000
2008年7月17日00:20:41记忆:289m计数:200000
2008年7月17日THU 17:21:41记忆:432m计数:300000
2008年7月17日THU 17:22:42记忆:574M计数:400000
2008年7月17日星期四00:23:47记忆:717m计数:500000
2008年7月17日THU 17:24:49记忆:860m计数:600000
2008年7月17日THU 17:25:51记忆:1002m计数:700000
2008年7月17日THU 17:26:54记忆:1145m计数:800000
2008年7月17日星期四00:27:59记忆:1288M计数:900000
2008年7月17日THU 17:29:03记忆:1430m计数:1000000
2008年7月17日THU 17:30:07记忆:1573M计数:1100000
2008年7月17日00:31:11记忆:1716m计数:1200000
2008年7月17日00:32:15记忆:1859m计数:1300000
2008年7月17日00:33:23记忆:2001M计数:1400000
Trackback(最近的最新电话):
文件" c:c:\ test \ freedb \ tardemo.py",第40行,
对于TF中的Tarinfo:
文件" c:c:\ test \ freedb \ tarfilex.py",第2406行
tarinfo = self.tarfile.next()
文件" c:c:\ test \ freedb \ tarfilex.py",第2311行
tarinfo = self.tarinfo.fromtarfile(self)
文件" c:c:\ test \ freedb \ tarfilex.py",第1235行,在fromtarfile
obj = cls.frombuf(buf)
文件" c:c:\ test \ freedb \ tarfilex.py",第1193行,在frombuf
如果不在Calc_Chksums(BUF)中的Chksum:
文件" C:\ test \ freedb \ tarfilex.py",第261行,在Calc_chksums中
unsigned_chksum = 256 + sum(struct.unpack(" 148b",buf [:148]) +
struct.unpack(" 356b",buf [156:512]))))
MemoryError

# 回答1


在7月17日,10:01,Terry Carroll 我在当前的Python 2.5安装中查看了Tarfile.py
lib路径.迭代器在列表中缓存tarinfo对象
TF.会员.如果您只想迭代并且不感兴趣
在更多功能方面,您可以在内部使用" tf.members = []"
你的循环.这是一个肮脏的黑客!
问候,uwe
# 回答2


在2008年7月17日星期四06:14:45 -0700(PDT),Uwe Schmitt
谢谢,UWE.这对我来说很好.现在读取所有2.5
百万成员在大约30分钟内从未超过4m的工作
放.
# 回答3


在17年7月17日,Terry Carroll 谢谢,UWE. *对我来说很好. *现在读取所有2.5
百万成员在大约30分钟内从未超过4m的工作
放.
也许我们应该将此问题发布到Python-Dev邮件列表中.
解析大焦油文件并不少见.
问候,uwe
# 回答4


Uwe Schmitt在2008年7月17日上午10:39:23 AM -0700上写道:
谢谢,UWE. *对我来说很好. *现在读取所有2.5
百万成员在大约30分钟内从未超过4m的工作
放.

也许我们应该将此问题发布到Python-Dev邮件列表中.
par 唱大焦油文件并不少见. 此问题已知,并为Python 3.0修复,请参见http://bugs.python.org/issue2058. - - lars -gustäbellaxe@gustaebel.de EsgenügtNichtNur,Keine Gedanken Zu Haben, ManMußAuchunufähigSein,SieAuszudrücken. (匿名)

# 回答5

在7月17日,22:21,LarsGustäbel
# 回答6

由于上面的讨论,我写了一个用于扫描的Python模块 大型tarfiles. 您可以从http://www.procoders.net/wp-content/tarfile_scanner.zip获得它 问候,uwe

标签: python

添加新评论