如何在文件的特定位置插入而不是覆盖

时间:2018-09-10 12:17:40

标签: python python-3.x file

我正在尝试使用以下方法在文件的特定位置插入一些文本:

with open("test.txt","r+") as f:
    f.seek(5)
    f.write("B")

但是,这会使用新数据(“ B”)覆盖位置5的字符,而不是插入它。

例如,如果我有

AAAAAAAAAA
在文件test.txt

并运行代码 我得到的是AAAAABAAAA而不是AAAAABAAAAA(五个A必须在B之后)

我如何在文件的所需位置插入而不是覆盖?

3 个答案:

答案 0 :(得分:1)

这对我有用:

with open("test.txt","r+") as f:
    f.seek(5) #first fseek to the position
    line=f.readline() #read everything after it
    f.seek(5) #since file pointer has moved, fseek back to 5
    f.write("B") #write the letter
    f.write(line) #write the remaining part

Original : AAAAAAAAAA

After :    AAAAABAAAAA 

答案 1 :(得分:1)

有三个答案:

  1. 通用文件API(在所有操作系统上都希望使用)没有用于“插入”的接口(阅读:这是不可能的)
  2. 您可以通过将整个文件读入内存,编写新内容并将其写回来自己实现此目的。 (如果文件很大,则可能需要创建一些代码来分批执行此操作。)
  3. 对于linux用户来说是个好消息:从linux 3.15开始,可以在文件中间插入孔(基本上是,从特定偏移量的特定位置开始移动文件中的所有内容)。这里有关于此主题的详尽文章:https://lwn.net/Articles/629965/。 ext4和XFS文件系统支持它,并且它需要在fd上进行一些低级操作(例如,对于Python来说,不是通常的open)。此外,正如我在2018年9月检查的那样,pypi上的fallocate模块不支持它,因此您需要编写一个低级代码来执行FALLOC_FL_INSERT_RANGE ioctl。

TL; DR;如果文件很小,则将其读入内存并插入内存。如果文件中等大小(1-2Gb),请在临时文件中进行处理,然后重命名。如果您的文件很大,请使用窗口操作或深入研究FALLOC_FL_INSERT_RANGE(如果您使用的是相对较新的linux)。

答案 2 :(得分:1)

f1 = open("test.txt","r+")
f1.seek(5)
data = "{}{}".format("B",f1.readline())
f1.seek(5)
f1.write(data)
f1.close()