0

I'm trying to insert some text at specific position of file using this:

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

But this overwrites character at position 5 with new data ("B") instead of inserting it.

for example if i have

AAAAAAAAAA

in file test.txt and run the code I get AAAAABAAAA instead of AAAAABAAAAA (five A must be after B)

How can i insert at desired position of file instead of overwrite?

Ariyan
  • 14,760
  • 31
  • 112
  • 175

3 Answers3

1

This worked for me :

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 
Sruthi
  • 2,908
  • 1
  • 11
  • 25
1

There are three answers for that:

  1. Generic file API (one you expect on all OSes) have no interface for 'insert' (read: this is impossible)
  2. You can implement this by yourself, by reading whole file into memory, composing new content and writing it back. (If file is big, you may need to create some code to do this in chunks).
  3. Good news for linux users: Since linux 3.15 it's possible to insert holes in the middle of the file (basically, shifting everything in file starting from specific location of a specific offset). There is a comprehensive article on this topic here: https://lwn.net/Articles/629965/. It is supported for ext4 and XFS filesystems, and it requires some low-level operations on fd (e.f. not the usual open for the python). Moreover, as I checked (Sep 2018) a fallocate module on pypi does not support it, so you need to write a low-level code to do FALLOC_FL_INSERT_RANGE ioctl.

TL;DR; If you file is small, read it into memory and do insert in memory. If you file is medium size (1-2Gb) do it in temp file and rename it after that. If your file is large, use windowed operations or dig down to FALLOC_FL_INSERT_RANGE (if you have a relatively modern linux).

George Shuklin
  • 6,952
  • 10
  • 39
  • 80
1
f1 = open("test.txt","r+")
f1.seek(5)
data = "{}{}".format("B",f1.readline())
f1.seek(5)
f1.write(data)
f1.close()
wailinux
  • 139
  • 4