Операции с файлами на Python

Я получил ошибку "IOError: [Errno 0] Error" с этой программой python:

from sys import argv
file = open("test.txt", "a+")
print file.tell() # not at the EOF place, why?
print file.read() # 1
file.write("Some stuff will be written to this file.") # 2
# there r some errs when both 1 & 2
print file.tell()
file.close()

Какая проблема? Эти два случая ниже:

from sys import argv
file = open("test.txt", "a+")
print file.tell() # not at the EOF place, why?
# print file.read() # 1
file.write("Some stuff will be written to this file.") # 2
# there r some errs when both 1 & 2
print file.tell()
file.close()

и

from sys import argv
file = open("test.txt", "a+")
print file.tell() # not at the EOF place, why?
print file.read() # 1
# file.write("Some stuff will be written to this file.") # 2
# there r some errs when both 1 & 2
print file.tell()
file.close()

все еще, почему

print file.tell() # not at the EOF place, why?

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

Я использую Windows 7 и Python 2.7.

Ответ 1

Python использует функцию stdio fopen и передает режим в качестве аргумента. Я предполагаю, что вы используете окна, поскольку @Lev говорит, что код отлично работает в Linux.

Ниже приведена fopen документация по окнам, это может быть ключом к решению вашей проблемы:

Когда указывается тип доступа "r +", "w +" или "a +", оба чтения и запись разрешена (файл считается открытым для "обновления" ). Однако, когда вы переключаетесь между чтением и письмом, должно быть вмешательство fflush, fsetpos, fseek или перемотка назад. Электрический ток позиция может быть указана для операции fsetpos или fseek, если желательно.

Итак, решение состоит в том, чтобы добавить file.seek() перед вызовом file.write(). Для добавления к концу файла используйте file.seek(0, 2).

Для вашей справки file.seek работает следующим образом:

Чтобы изменить положение объектов файла, используйте f.seek(offset, from_what). Позиция вычисляется добавлением смещения к точке отсчета; контрольная точка выбирается аргументом from_what. A from_what значение 0 мер с начала файла, 1 использует текущий положение файла, а 2 использует конец файла в качестве контрольной точки. from_what можно опустить и по умолчанию 0, используя начало файл в качестве исходной точки.

[ссылка: http://docs.python.org/tutorial/inputoutput.html]

Как упоминалось в комментариях @lvc и @Burkhan в его ответе, вы можете использовать новую открытую функцию из io module. Тем не менее, я хочу отметить, что функция записи не работает точно так же в этом случае - вам нужно указать строки unicode в качестве входных данных [просто префикс a u для строки в вашем случае]:

from io import open
fil = open('text.txt', 'a+')
fil.write('abc') # This fails
fil.write(u'abc') # This works

Наконец, пожалуйста, избегайте использования имени "файл" в качестве имени переменной, поскольку оно относится к встроенному типу и будет бесшумно переписываться, что приводит к некоторым трудным для обнаружения ошибкам.

Ответ 2

Решение состоит в использовании open из io

D:\>python
Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> f = open('file.txt','a+')
>>> f.tell()
0L
>>> f.close()
>>> from io import open
>>> f = open('file.txt','a+')
>>> f.tell()
22L