Открыть файл для случайной записи без усечения?

В python есть несколько флагов, которые вы можете предоставить при открытии файла для работы. Я немного озадачен поиском комбинации, которая позволяет мне делать случайную запись без усечения. Поведение, которое я ищу, эквивалентно C: создать его, если оно не существует, в противном случае открыть для записи (не обрезать)

open(filename, O_WRONLY|O_CREAT)

Python документ запутан (для меня): "w" сначала обрезает файл, "+" должен означать обновление, но "w+" будет усекать это так или иначе. В любом случае, чтобы достичь этого, не прибегая к низкоуровневому интерфейсу os.open()?

Примечание: "a" или "a+" тоже не работает (пожалуйста, исправьте, если я делаю что-то не так)

cat test.txt
eee

with open("test.txt", "a+") as f:
  f.seek(0)
  f.write("a")
cat test.txt
eeea

Это значит, что режим append настаивает на записи до конца?

Ответ 1

Вы должны открыть в режиме rb+.

with open("file", "rb+") as file:
    file.write(b"...")

На Python 2 вы можете использовать r+ вместо текстового режима, но не должны, так как он может изменить длину текста, который вы пишете.

Ответ 2

Вам нужно использовать "a" для добавления, он создаст файл, если он не существует или не добавляется к нему, если он это делает.

Вы не можете делать то, что хотите, с добавлением, поскольку указатель автоматически перемещается в конец файла при вызове метода записи.

Вы можете проверить, существует ли файл, затем используйте fileinput.input с inplace=True, вставляя строку на любой номер строки, который вы хотите.

import fileinput
import os


def random_write(f, rnd_n, line):
    if not os.path.isfile(f):
        with open(f, "w") as f:
            f.write(line)
    else:
        for ind, line in enumerate(fileinput.input(f, inplace=True)):
            if ind == rnd_n:
                print("{}\n".format(line) + line, end="")
            else:
                print(line, end="")

http://linux.die.net/man/3/fopen

а + Открыть для чтения и добавления (запись в конце файла). Файл создается, если он не существует. Начальная позиция файла для чтения находится в начале файла, но вывод всегда добавляется в конец файла.

fileinput делает копию f.bak файла, который вы передаете, и удаляется, когда выход закрыт. Если вы укажете расширение для резервного копирования backup=."foo", файл резервной копии будет сохранен.

Ответ 3

Вы можете сделать это с помощью os.open:

import os
f = os.fdopen(os.open(filename, os.O_RDWR | os.O_CREAT), 'rb+')

Теперь вы можете читать, писать в середине файла, искать и т.д. И он создает файл. Протестировано на Python 2 и 3.