Question

Currently teaching myself Python, and learning file I/O by writing a script to both read from and add text to an existing file. The script runs up until I call the write() method, at which point it throws out a non-specific exception - this is the traceback:

            File "test.py", line 13, in <module>
                f.write(txt)
            IOError: [Errno 0] Error

My code:

            from sys import argv

            script, filename = argv

            f = open(filename, 'a+')

            print("The contents of %s are:") % filename

            print f.read()

            txt = raw_input("What would you like to add? ")

            f.write(txt)

            print("The new contents are:")

            print f.read()

            f.close()

My environment is Python 2.7.3 in Win7, PowerShell, and Notepad++.

What is causing this? How would I fix it? In my understanding, the a+ access mode should allow me to both read and append to the file. Changing the access mode to r+ yields the same exception.

Clarifications:

  • I have an existing text file (a.txt) with a single word in it that I pass as an argument to the script, like so:

            python test.py a.txt
    
  • I am under an admin account in Windows.

Results:

At the minimum, adding two seek() commands fixes the issue - detailed in the answer post.

Was it helpful?

Solution

A problem when one tries to add a text of little size: it remains in the buffer, that keeps the text before the real writing is done after receiving more data.
So, to be sure to write really, do as it is described in the doc concerning os.fsync() and flush()

By the way, it is better to use the with statement.

And it's still more better to use binary mode. In your case, there shouldn't be a problem because you just add text after the reading and just use seek(o,o) . But when one wants to move correctly the file's pointer into the bytes of the file, it is absolutely necessary to use binary mode [ the 'b' in open(filename, 'rb+') ]

I personnaly never use 'a+', I've never understood what are its effects.

from sys import argv
from os import fsync

script, filename = argv

with open(filename, 'rb+') as f:
    print("The contents of %s are:") % filename
    print f.read()

    f.seek(0,2)
    txt = raw_input("What would you like to add? ")
    f.write(txt)
    f.flush()
    fsync(f.fileno())

    f.seek(0,0)
    print("The new contents are:")
    print f.read()

OTHER TIPS

For some reason print f.read() doesn't work for me on OS X when you have opened the file in a+ mode.

On Max OS X, changing the open mode to r+ and then adding a f.seek(0) line before the second read makes it work. Sadly, this doesn't help windows.

This is the working code on Mac OS:

from sys import argv

script, filename = argv

f = open(filename, 'r+')

print("The contents of %s are:") % filename

print f.read()

txt = raw_input("What would you like to add? ")

f.write(txt)

print("The new contents are:")

f.seek(0)
print f.read()

f.close()

This is the only way I could get it to work on windows 7:

from sys import argv

script, filename = argv

f = open(filename, 'r')

print("The contents of %s are:") % filename

print f.read()
f.close()

txt = raw_input("What would you like to add? ")

f = open(filename, 'a')
f.write(txt)
f.close()
f = open(filename, 'r')

print("The new contents are:")

print f.read()

f.close()

Which seems super hacky. This should also work on Mac OS X too.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top