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

问题描述 投票:0回答:3

这个问题在这里已有答案:

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

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

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

例如,如果我有

AAAAAAAAAA

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

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

python python-3.x file
3个回答
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)。


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
投票
f1 = open("test.txt","r+")
f1.seek(5)
data = "{}{}".format("B",f1.readline())
f1.seek(5)
f1.write(data)
f1.close()
© www.soinside.com 2019 - 2024. All rights reserved.