我使用以下简单的Python脚本在EC2 m3.large实例上压缩大型文本文件(例如10GB)。但是,我总是得到MemoryError
:
import gzip
with open('test_large.csv', 'rb') as f_in:
with gzip.open('test_out.csv.gz', 'wb') as f_out:
f_out.writelines(f_in)
# or the following:
# for line in f_in:
# f_out.write(line)
我得到的追溯是:
Traceback (most recent call last):
File "test.py", line 8, in <module>
f_out.writelines(f_in)
MemoryError
我已经阅读了有关此问题的一些讨论,但仍不清楚如何处理。有人可以给我一个关于如何处理此问题的更容易理解的答案吗?
真奇怪 如果您尝试压缩不包含许多换行符的大型二进制文件,则可能会出现此错误,因为这样的文件可能包含对RAM而言太大的“行”,但不应在行上发生-结构化的.csv文件。
但是无论如何,逐行压缩文件并不是很有效。即使OS缓存的磁盘I / O是一般多少更快地读取和写入较大的数据块,如64 KB。
我在这台机器上有2GB的RAM,并且我刚刚成功使用下面的程序压缩了2.8GB的tar存档。
#! /usr/bin/env python
import gzip
import sys
blocksize = 1 << 16 #64kB
def gzipfile(iname, oname, level):
with open(iname, 'rb') as f_in:
f_out = gzip.open(oname, 'wb', level)
while True:
block = f_in.read(blocksize)
if block == '':
break
f_out.write(block)
f_out.close()
return
def main():
if len(sys.argv) < 3:
print "gzip compress in_file to out_file"
print "Usage:\n%s in_file out_file [compression_level]" % sys.argv[0]
exit(1)
iname = sys.argv[1]
oname = sys.argv[2]
level = int(sys.argv[3]) if len(sys.argv) > 3 else 6
gzipfile(iname, oname, level)
if __name__ == '__main__':
main()
我正在运行Python 2.6.6,gzip.open()
但不支持with
。
正如安德鲁·贝(Andrew Bay)在评论中指出的那样if block == '':
,由于它block
包含字节而不是字符串,因此在Python 3中无法正常工作,并且空字节对象不等于空文本字符串。我们可以检查代码块的长度,也可以进行比较b''
(也可以在Python 2.6+中使用),但是简单的方法是if not block:
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句