15

I got an err "IOError: [Errno 0] Error" with this python program:

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()

what seems to be the problem? These 2 cases below are ok:

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()

and:

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()

still, why

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

does not print the size of the file, is "a+" the append-mode? then the file pointer should point to EOF?

i'm using Windows 7 and Python 2.7.

5
  • Where do you get the error? The problem seems to be that you're trying to read a file opened in append mode Commented Jun 24, 2012 at 10:37
  • Also, are you sure that text.txt exists? Commented Jun 24, 2012 at 10:40
  • Your code works fine for me. tell returns 0 just after opening the file, of course, why would you expect anything else? Commented Jun 24, 2012 at 10:43
  • Can you add the version of Python you are using and the operating system? Commented Jun 24, 2012 at 10:55
  • See my updated answer, this fix should work. I tried it on the same platform+python version as you Commented Jun 24, 2012 at 11:22

2 Answers 2

13

Python uses stdio's fopen function and passes the mode as argument. I am assuming you use windows, since @Lev says the code works fine on Linux.

The following is from the fopen documentation of windows, this may be a clue to solving your problem:

When the "r+", "w+", or "a+" access type is specified, both reading and writing are allowed (the file is said to be open for "update"). However, when you switch between reading and writing, there must be an intervening fflush, fsetpos, fseek, or rewind operation. The current position can be specified for the fsetpos or fseek operation, if desired.

So, the solution is to add file.seek() before the file.write() call. For appending to the end of the file, use file.seek(0, 2).

For your reference, file.seek works as follows:

To change the file object’s position, use f.seek(offset, from_what). The position is computed from adding offset to a reference point; the reference point is selected by the from_what argument. A from_what value of 0 measures from the beginning of the file, 1 uses the current file position, and 2 uses the end of the file as the reference point. from_what can be omitted and defaults to 0, using the beginning of the file as the reference point.

[reference: http://docs.python.org/tutorial/inputoutput.html]

As mentioned by @lvc in the comments and @Burkhan in his answer, you can use the newer open function from the io module. However, I want to point out that the write function does not work exactly the same in this case -- you need to provide unicode strings as input [Simply prefix a u to the string in your case]:

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

Finally, please avoid using the name 'file' as a variable name, since it refers to a builtin type and will be silently over-written, leading to some hard to spot errors.

Sign up to request clarification or add additional context in comments.

9 Comments

@LevLevitsky, I couldn't make sure of that from the documentation, but you're right, the code works
Moreover, it opens non-existent files without any errors, too.
Yep, but it fails when the file has some text in it
It doesn't, at least on my system.
I am using windows, Python 2.7, what about you?
|
6

The solution is to use open from 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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.