使用Python拆分大文件
我在处理一些大文件(比如大约10GB的文件)时遇到了一些麻烦。我的基本想法是读取文件的每一行,然后把每40000行分成一个文件。
但是,读取文件有两种方式。
1) 第一种是一次性读取整个文件,把它变成一个列表。但这样做需要把整个文件都加载到内存中,对于这么大的文件来说,这会很麻烦。(我想我之前问过类似的问题)在Python中,我尝试过的读取整个文件的方法包括:
input1=f.readlines()
input1 = commands.getoutput('zcat ' + file).splitlines(True)
input1 = subprocess.Popen(["cat",file],
stdout=subprocess.PIPE,bufsize=1)
这样的话,我就可以很简单地把40000行分成一个文件,比如用:list[40000,80000] 或 list[80000,120000]
。使用列表的好处是我们可以很方便地指向特定的行。
2) 第二种方式是逐行读取;在读取每一行时就处理它。这样读取的行不会保存在内存中。例子包括:
f=gzip.open(file)
for line in f: blablabla...
或者
for line in fileinput.FileInput(fileName):
我知道对于gzip.open,这里的f不是一个列表,而是一个文件对象。看起来我们只能逐行处理;那么我该如何执行这个“分割”的任务呢?我该如何指向文件对象的特定行呢?
谢谢
8 个回答
4
我找到的最佳解决方案是使用一个叫做 filesplit 的库。
你只需要指定输入文件、输出文件夹和你想要的输出文件大小(以字节为单位)。最后,这个库会帮你完成所有的工作。
from fsplit.filesplit import Filesplit
def split_cb(f, s):
print("file: {0}, size: {1}".format(f, s))
fs = Filesplit()
fs.split(file="/path/to/source/file", split_size=900000, output_dir="/pathto/output/dir", callback=split_cb)
5
如果你对每个文件的行数没有特别的要求,readlines()
函数 还可以接受一个叫做 'size hint' 的参数,它的作用是这样的:
当你给它一个可选的参数 sizehint 时,它会从文件中读取那么多字节,并且会多读一些字节以确保读取到完整的一行,然后返回这些行。这个功能通常用来高效地按行读取大文件,而不需要把整个文件都加载到内存中。返回的只会是完整的行。
...所以你可以把代码写成这样:
# assume that an average line is about 80 chars long, and that we want about
# 40K in each file.
SIZE_HINT = 80 * 40000
fileNumber = 0
with open("inputFile.txt", "rt") as f:
while True:
buf = f.readlines(SIZE_HINT)
if not buf:
# we've read the entire file in, so we're done.
break
outFile = open("outFile%d.txt" % fileNumber, "wt")
outFile.write(buf)
outFile.close()
fileNumber += 1
21
NUM_OF_LINES=40000
filename = 'myinput.txt'
with open(filename) as fin:
fout = open("output0.txt","wb")
for i,line in enumerate(fin):
fout.write(line)
if (i+1)%NUM_OF_LINES == 0:
fout.close()
fout = open("output%d.txt"%(i/NUM_OF_LINES+1),"wb")
fout.close()
当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。