{ File I/O Introduction. }

Objectives:

By the end of this chapter, you should be able to:

  • Read and write to text files
  • Explain the purpose of a with statement
  • Explain the different ways to open a file depending on whether you want to read, write, or append

Definitions

Python has a lot of functionality to help you manipulate text files. In this chapter we'll explore some of this functionality. Before we do so, here are three terms you should know, as we'll be using them frequently when discussing file IO (input/output).

Reading - Getting data from a file. The data can be stored and manipulated in your program.

Writing - Saving new data to a file.

Cursor - When you read a file, a cursor gets created (just like a cursor when you are typing). You can't see this cursor, but this is how you can tell a file where to start reading from. Once the cursor is at the end of a file, you can not read it anymore unless you explicitly go back to the beginning

Reading

Let's start by creating a text file called first.txt and placing the following text inside of it:

This is a very simple text file!

Now let's make a file called read.py and add the following.

file = open('first.txt', 'r')
print(file.read())

We just opened a file called first.txt for reading (that's what the second argument of 'r' indicates). After opening the file and storing it in a variable called file, we call the read function on it, which allows us to move our cursor from the beginning to the end. Finally, we're not just reading the file; we're printing out the results of that read operation. If you run python3 read.py in Terminal (from the directory where read.py lives), you should see the text of the file in the terminal!

If we try to make invoke file.read() a second time, we just get an empty string back. This is because the cursor is at the end of the file and there is no more to read. In order to read the file again, we'll need to go back to the beginning of the file using seek. Hop into the Python REPL by typing python3 in the terminal, then execute the following code:

file = open('first.txt', 'r')

# type in the following commands

file.read() # we see all our test
file.read() # nothing now!

file.seek(0) # move the cursor back to the beginning
file.read() # there it is!

But we're not done yet, if we look at file.closed we will see the value is False. So we opened our file, but we never closed it! Let's always make sure we close the file!

file = open('first.txt', 'r')

# type in the following commands

file.read() # we see all our test
file.read() # nothing now!

file.seek(0) # move the cursor back to the beginning
file.read() # there it is!

file.closed # False
file.close()
file.closed # True

file.read() # ValueError: I/O operation on closed file

Note: for multiline files, you can read one line at a time using the readline method.

keyword with

Instead of worrying about closing the file each time, we can use a with block, which will automatically close the file after the operation. Let's see what that looks like:

with open('first.txt', 'r') as file:
    data = file.read()
    print(data)

file.closed # True

Writing

In the previous examples, we've seen that the open function takes two parameters. The first is the path to the text file. But what's the second? Here is where we tell Python what we intend to do with the file. Here are the options for what we can pass in:

  • r use this when you only want to read the file.
  • r+ use this when you want to read and write to the file. In this case, if you write to the file, you'll overwrite any existing characters while you're writing based on the location of the cursor, but once you've finished writing, other characters will be unaffected.
  • a use this when you want to append to the file (text that's already in the file won't be affected)
  • a+ use this when you want to read the file and append to it.
  • w use this when you want to write to the file. In this case, the file is completely emptied before it's written to, so the original text data will be lost.
  • w+ use this when you want to write and read to the file.

If you don't pass anything in to the second argument to open, r will be assumed.

Take a look at these examples to see how these options behave differently:

with open('first.txt', 'w') as file:
    file.write('Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eos molestias ea sit veniam, rerum, totam quis eaque excepturi aut, nostrum reiciendis. At, harum quos adipisci magni nesciunt aliquid beatae sit!')

with open('first.txt', 'r') as file:
    print(file.read())

with open('first.txt', 'r+') as file:
    file.write("\nI'm at the beginning\n")
    file.seek(100)
    file.write("\nI'm in the middle\n")
    file.seek(0)
    print(file.read())

with open('first.txt', 'a+') as file:
    file.write("\nI'm at the end\n")
    file.seek(0)
    print(file.read())

with open('first.txt', 'w+') as file:
    file.write("Now everything is overwritten :(")
    file.seek(0)
    print(file.read())

When you're ready, move on to File I/O with CSVs

Continue