就地修改Python文件
我有一个很大的xml文件(40GB),我需要把它分成几个小文件。因为我的存储空间有限,所以我想知道有没有办法在把内容写入新文件的同时,从原文件中删除那些行?
谢谢!
7 个回答
1
我很确定是可以做到的,因为我甚至能编辑和读取我运行过的脚本的源文件。不过,最大的麻烦可能是如果你从文件的开头开始处理,文件内容会不断移动。另一方面,如果你先浏览文件,记录下每一行的起始位置,然后可以按照这些位置的倒序来提取行;一旦完成,你可以逐个处理新文件(如果它们足够小),用readlines()生成一个列表,反转这个列表的顺序,然后回到文件开头,用新顺序的行覆盖旧顺序的行。
(你可以在读取完最后一块行后,使用truncate()
方法来截断文件,这个方法会删除当前文件位置之后的所有数据。如果你使用的是io
包中的类或其子类来读取文件,确保当前文件位置在要写入新文件的最后一行的开头。)
编辑:根据你提到的需要在正确的结束标签处进行分隔,你可能还需要开发一个算法来检测这些标签(也许可以使用peek
方法),可能还需要用到正则表达式。
7
假设你想把一个文件分成N个部分,那么你可以从文件的后面开始读取(大致上这样做),然后不断调用truncate这个方法:
这个方法可以用来缩小文件的大小。如果你提供了一个可选的大小参数,文件会被缩小到这个大小(最多到这个大小)。如果没有提供,默认会缩小到当前的位置。注意,当前文件的位置不会改变。...
import os
import stat
BUF_SIZE = 4096
size = os.stat("large_file")[stat.ST_SIZE]
chunk_size = size // N
# or simply set a fixed chunk size based on your free disk space
c = 0
in_ = open("large_file", "r+")
while size > 0:
in_.seek(-min(size, chunk_size), 2)
# now you have to find a safe place to split the file at somehow
# just read forward until you found one
...
old_pos = in_.tell()
with open("small_chunk%2d" % (c, ), "w") as out:
b = in_.read(BUF_SIZE)
while len(b) > 0:
out.write(b)
b = in_.read(BUF_SIZE)
in_.truncate(old_pos)
size = old_pos
c += 1
要小心,因为我没有测试过这些内容。可能在调用truncate之后需要调用一下flush
,而且我也不知道文件系统实际释放空间的速度会有多快。