我有一个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
答案 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
其他任何内容可能完全一样)。不同之处在于必须首先运行第一个循环。
基本上,在决定处理数据之前计算行数只是浪费时间。如果没有实际读取文件并计算它们,你就无法计算行数。