Новичок Python: чтение и запись в тот же файл - программирование
Подтвердить что ты не робот

Новичок Python: чтение и запись в тот же файл

Запустил Python неделю назад, и у меня есть некоторые вопросы, чтобы спросить о чтении и записи в те же файлы. Я прошел через некоторые учебники онлайн, но я все еще смущен. Я могу понять простые файлы для чтения и записи.

openFile = open("filepath", "r")
readFile = openFile.read()
print readFile 

openFile = open("filepath", "a")
appendFile = openFile.write("\nTest 123")

openFile.close()

Но, если я попробую следующее, я получаю кучу неизвестного текста в текстовом файле, который я пишу. Может кто-нибудь объяснить, почему я получаю такие ошибки и почему я не могу использовать тот же объект openFile, как показано ниже.

# I get an error when I use the codes below:       
openFile = open("filepath", "r+")
writeFile = openFile.write("Test abc")

readFile = openFile.read()
print readFile

openFile.close()

Я попытаюсь прояснить свои проблемы. В приведенном выше примере openFile - это объект, используемый для открытия файла. У меня нет проблем, если я хочу писать в первый раз. Если я хочу использовать тот же openFile, чтобы читать файлы или добавлять что-то к нему. Этого не происходит или возникает ошибка. Я должен объявить один и тот же/другой открытый файл, прежде чем я могу выполнить другое действие чтения/записи в тот же файл.

#I have no problems if I do this:    
openFile = open("filepath", "r+")
writeFile = openFile.write("Test abc")

openFile2 = open("filepath", "r+")
readFile = openFile2.read()
print readFile

openFile.close()

Буду признателен, если кто-нибудь скажет мне, что я сделал не так, или это просто вещь Питонга. Я использую Python 2.7. Спасибо!

4b9b3361

Ответ 1

Обновленный ответ:

Это похоже на ошибку, характерную для Windows - http://bugs.python.org/issue1521491.

Цитата из обходного пути, описанного в http://mail.python.org/pipermail/python-bugs-list/2005-August/029886.html

эффект смешивания чтений с записью на файл, открытый для обновления, полностью undefined, если операция позиционирования файла не происходит между их (например, seek()). Я не могу догадаться, что вы ожидаете, что произойдет, но, скорее всего, можно надежно получить, вставив

fp.seek(fp.tell())

между read() и вашим write().

Мой первоначальный ответ демонстрирует, как чтение/запись в том же файле открываются для приложений добавления. По-видимому, это не так, если вы используете Windows.

Оригинальный ответ:

В режиме "r +" с помощью метода write будет записываться строковый объект в файл на основе указателя. В вашем случае он добавит строку "Test abc" в начало файла. См. Пример ниже:

>>> f=open("a","r+")
>>> f.read()
'Test abc\nfasdfafasdfa\nsdfgsd\n'
>>> f.write("foooooooooooooo")
>>> f.close()
>>> f=open("a","r+")
>>> f.read()
'Test abc\nfasdfafasdfa\nsdfgsd\nfoooooooooooooo'

Строка "foooooooooooooo" добавлена ​​в конце файла, так как указатель уже был в конце файла.

Вы используете систему, которая различает двоичные и текстовые файлы? В этом случае вы можете использовать "rb +" в качестве режима.

Добавить "b" в режим открытия файла в двоичном режиме, в системах которые различают двоичные и текстовые файлы; на системах, которые не имеют этого различия, добавив, что "b" не имеет никакого эффекта. http://docs.python.org/2/library/functions.html#open

Ответ 2

Каждый открытый файл имеет неявный указатель, который указывает, где будут считываться и записываться данные. Обычно это значение по умолчанию относится к началу файла, но если вы используете режим a (append), то по умолчанию он заканчивается в конце файла. Также стоит отметить, что режим w обрезает ваш файл (т.е. Удаляет все содержимое), даже если вы добавите + в режим.

Всякий раз, когда вы читаете или записываете N символов, указатель чтения/записи будет перемещать вперед эту сумму в файле. Я нахожу, что это помогает думать об этом, как о старой кассетной ленте, если вы их помните. Итак, если вы выполнили следующий код:

fd = open("testfile.txt", "w+")
fd.write("This is a test file.\n")
fd.close()

fd = open("testfile.txt", "r+")
print fd.read(4)
fd.write(" IS")
fd.close()

... Он должен закончиться печатью This, а затем оставить содержимое файла как This IS a test file.. Это связано с тем, что начальный read(4) возвращает первые 4 символа файла, потому что указатель находится в начале файла. Он оставляет указатель на символе пробела сразу после This, поэтому следующий write(" IS") перезаписывает следующие три символа пробелом (то же, что уже есть), за которым следует IS, заменяя существующий IS.

Вы можете использовать метод seek() файла для перехода к определенной точке. После примера выше, если вы выполнили следующее:

fd = open("testfile.txt", "r+")
fd.seek(10)
fd.write("TEST")
fd.close()

... Затем вы обнаружите, что файл теперь содержит This IS a test file..

Все это применимо к Unix-системам, и вы можете проверить эти примеры, чтобы убедиться. Однако у меня были проблемы с смешиванием read() и write() в системах Windows. Например, когда я запускаю этот первый пример на моей машине Windows, он корректно печатает This, но после проверки файла write() был полностью проигнорирован. Однако второй пример (с использованием seek()), похоже, отлично работает в Windows.

В общем, если вы хотите читать/писать из середины файла в Windows, я бы предложил всегда использовать явный seek() вместо того, чтобы полагаться на позицию указателя чтения/записи. Если вы делаете только чтение или запись, то это довольно безопасно.

Один последний момент - если вы указываете пути в Windows как литеральные строки, не забудьте избежать обратных косых черт:

fd = open("C:\\Users\\johndoe\\Desktop\\testfile.txt", "r+")

Или вы можете использовать необработанные строки, поставив r в начале:

fd = open(r"C:\Users\johndoe\Desktop\testfile.txt", "r+")

Или самая портативная опция - использовать os.path.join():

fd = open(os.path.join("C:\\", "Users", "johndoe", "Desktop", "testfile.txt"), "r+")

Более подробную информацию о файле IO вы можете найти в официальных документах официальных документов Python.

Ответ 3

Чтение и запись происходит там, где находится текущий указатель на файл, и он продвигается с каждым чтением/записью. В вашем конкретном случае запись в openFile приводит к тому, что указатель файла указывает на конец файла. Попытка прочитать с конца приведет к EOF. Вам нужно reset указатель файла, чтобы перед началом чтения указать перед началом файла до seek(0)