在遍历文件中的行时如何从文件中删除行?

时间:2019-03-21 17:18:33

标签: python python-3.x ubuntu ubuntu-16.04

我正在运行带有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'

我该怎么做?

3 个答案:

答案 0 :(得分:1)

您在这里遇到了一个大问题:在大多数操作系统及其文件系统上,删除文件的中间内容并不是您可以做的,而且如果可以的话,这是一项复杂而复杂的约束操作。

因此,从文件中间删除的通常方法是重写整个文件。但是您似乎在注释中指出您的文件为数百GB。因此,读取整个文件,处理一行并重写整个文件将非常昂贵,并且需要额外的临时存储空间。如果您想对每一行都执行此操作,最终将需要做更多的工作,并且仍然需要大约两倍的磁盘空间。

如果您绝对必须这样做,则有以下几种可能性:

  • 向后读取文件,并在运行时将其截断。向后读取它会很尴尬,因为没有太多设置可以帮助解决此问题,但是原则上这是可能的,并且您可以 truncate这样的文件结尾不需要复制它。
  • 使用较小的文件,并在处理每个文件后将其删除。这取决于您是否能够更改文件的创建方式,但是如果可以的话,它要简单得多,并且可以更快地删除处理过的片段。

另一方面,您确实需要吗?是否存在文件太大的问题,如果数据库仍在磁盘上,数据库将耗尽空间?还是只想同时处理更多大文件?如果是后者,您是否检查过同时处理多个文件实际上比一个接一个地处理更快?当然,您可以购买更多磁盘还是更大磁盘?

答案 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文件的内部结构。