获取gzip压缩文件

时间:2015-10-05 10:25:45

标签: python

我有一个Python脚本,它在gzip压缩文件上执行一些操作。我想在处理文件之前检查文件是否为空文件。我在SO中看到了一些暗示使用它的东西:

isize = U32(read32(self.fileobj))

但这对我测试的0kb utf文件不起作用。此方法也有一个约束,它只能用于少于4演出的文件。

我这样做了,可以得到文件的行数:

input_file = gzip.open(argv[0], 'rb')
row_count= len(list(input_file))
print "file rows size", row_count
if (row_count==0):
    print ('Input file has no records.')
    sys.exit(0)

input_file.seek(0)

但这是有效的,因为我的输入文件大小> 70gigs。

编辑:如果文件是0 kb文件,我的要求是跳过处理。但是压缩UTF文件使其成为1kb,所以我也无法检查它。还有其他方法吗?

如果文件有,我还想跳过整个过程 1.没有行 2.空行即。 \n' S

1 个答案:

答案 0 :(得分:2)

除非您的计算机具有96GiB RAM左右,否则它效率不高。你应该做的是不把行放在一个列表中(这将占用大量内存),最好你应该一次处理数据。

您的要求从一开始就不明确,但似乎您根本不​​必计算行数。刚开始处理文件,如果它是空的,你会在发现它时处理它:

input_file = gzip.open(argv[0], "rb")

for l in input_file:
    process_line(l)
    row_count += 1

print "file rows size", row_count
# etc

请注意,如果文件不包含任何行,则循环将立即终止,您将转到print语句。如果您有很多空行应该跳过,也就是跳过它们,情况也是如此。

您应该只读一次文件,因为否则必须(因为您可能没有96GiB的RAM)要么解压缩文件两次,要么必须将解压缩的数据存储在临时文件中(如果你试着把它放在一个列表中,它只会在你的交换文件中结束,而且不会更好。)

为了分析差异,我们可以先考虑构造:

row_count = len([l for l in input_file if condition(x)])

并与

进行比较
row_count = 0
for l in input_file:
    if condition(l):
        row_count += 1

两个构造都必须读取input_file以提取所有行并评估python表达式condition(x),这两者是相同的。在这两个计数和循环中都涉及到,在第一种情况下,在C中比在第二种情况下完成更多,这可能导致某人认为前者更快。主要区别在于第一个是在RAM中存储行列表,当RAM用尽时,数据将改为交换文件,并且使用更多C节省的少量时间不太可能超过此值(即使您实际创建列表的事实可能足以抵消这种优势)。

现在我们已经看到两种技术都会读取整个input_file以确定是否有待处理的行,并且这可能无法避免(特别是在涉及条件的情况下)。现在,首先检查行数,然后处理文件,与刚刚过程和过程方法进行比较:

row_count = 0
for l in input_file:
    if condition(l):
        row_count += 1

input_file.seek(0)
if row_count > 0:
    for l in input_file:
        if condition(l):
            process_line(l)

比较
row_count = 0
for l in input_file:
    if condition(l):
        process_line(l)
        row_count += 1

让我们考虑一下在没有处理任何行的情况下,您将在这两种情况下遍历文件并评估condition(l)(评估为False)。然后你就完成了。没有重大差异(实际上存在细微差别,因为在第二种情况下,您不必检查row_count的值以查看您是否已完成)。

如果有要处理的行,则第一种方法中的第二个循环和第二个循环中的循环几乎相同(如果您不需要row_count其他任何内容可能完全一样)。不同之处在于必须首先运行第一个循环。

基本上,在决定处理数据之前计算行数只是浪费时间。如果没有实际读取文件并计算它们,你就无法计算行数。