我正在运行带有Python 3.6.8的Ubuntu 16.04 LTS,并且我具有以下代码,该代码使我可以遍历文件中的行,在其中处理每一行并将数据追加到数据库中。我需要处理一行,然后将其删除或将其替换为\n
或采取任何措施来减小文本文件的文件大小。另外,我最多需要该文件的2个副本:数据库和第一行删除的文件。
with open(filename, buffering=1000) as f:
for rows in f:
#process text
#delete row or replace with '\n'
我该怎么做?
答案 0 :(得分:1)
您在这里遇到了一个大问题:在大多数操作系统及其文件系统上,删除文件的中间内容并不是您可以做的,而且如果可以的话,这是一项复杂而复杂的约束操作。
因此,从文件中间删除的通常方法是重写整个文件。但是您似乎在注释中指出您的文件为数百GB。因此,读取整个文件,处理一行并重写整个文件将非常昂贵,并且需要额外的临时存储空间。如果您想对每一行都执行此操作,最终将需要做更多的工作,并且仍然需要大约两倍的磁盘空间。
如果您绝对必须这样做,则有以下几种可能性:
另一方面,您确实需要吗?是否存在文件太大的问题,如果数据库仍在磁盘上,数据库将耗尽空间?还是只想同时处理更多大文件?如果是后者,您是否检查过同时处理多个文件实际上比一个接一个地处理更快?当然,您可以购买更多磁盘还是更大磁盘?
答案 1 :(得分:1)
您可以重写文件的某些部分,因为长度不能更改,因此您不能随意插入/删除文件。
如果文件的最终使用者忽略了#
注释行或空格,那么您很高兴。
用数据库的话来说,每个记录都带有一个type属性,我们将其描述为将记录类型设置为“逻辑删除”。
阅读每一行或每一块时,请使用tell()
查找其起始文件位置。
决定是否删除它。
如果是这样,请使用seek()
备份到该位置,
和write()
空白记录上的空白(例如空白+ \n
换行符)。
然后继续阅读。
答案 2 :(得分:0)
这是唯一的文件分块方式:
def chunked(file, chunk_size):
return iter(lambda: file.read(chunk_size), '')
f = open('read_big_file.text', 'r')
for data in chunked(f, 65536):
# do something with the data
还有其他方法可以完成此任务。最后,您仍然必须删除较大的文件,因为此方法只是从原始文件中删除一些内容。
顺便说一句-您正在处理哪种类型的文件?
更新
上面的答案旨在将文件分割成较小的段,可以使用其他代码进行处理,需要添加这些代码。我已经使用这种方法来处理文本文件和CSV文件,但没有处理JSON。
JSON文件具有内部结构,因此当当前的分块代码将文件分成小段时,输出将不是有效的JSON。由于JSON文件是字典和列表相互嵌套的组合,因此最有可能破坏同一列表的JSON分隔元素。不知道JSON的确切结构,几乎不可能提供完整的答案,因为该答案取决于JSON文件的内部结构。