DEV Community

Cover image for Reading Files Without Breaking Everything
Akhilesh
Akhilesh

Posted on

Reading Files Without Breaking Everything

Every program you have written so far forgets everything the moment it stops running.

You store names in variables. You calculate scores. You build lists. Then the program ends and all of it is gone. Next time you run it, you start from zero again.

Files are how programs remember things between runs. Files are also how programs talk to the outside world. Real data lives in files. CSV files full of numbers. Text files full of sentences. JSON files full of structured data. Your AI models will read thousands of files. You need to know how this works.


Opening and Reading a File

First, create a file to practice with. Make a new file called notes.txt in the same folder as your Python files. Put this inside it:

Alex
Priya
Sam
Jordan
Lisa
Enter fullscreen mode Exit fullscreen mode

Just five names, one per line. Save it.

Now read it with Python.

file = open("notes.txt", "r")
content = file.read()
file.close()

print(content)
Enter fullscreen mode Exit fullscreen mode

Output:

Alex
Priya
Sam
Jordan
Lisa
Enter fullscreen mode Exit fullscreen mode

Three steps. Open the file. Do something with it. Close it.

The "r" means read mode. You're opening the file to read it, not change it.

file.read() grabs the entire file content as one big string.

file.close() is important. An open file uses system resources. If you forget to close it, you can run into problems, especially if your program opens many files.


The Better Way: with

Forgetting file.close() is a common mistake. Python has a cleaner approach that closes the file automatically, no matter what happens.

with open("notes.txt", "r") as file:
    content = file.read()

print(content)
Enter fullscreen mode Exit fullscreen mode

Same result. But now you don't need to call .close(). When the with block ends, Python closes the file automatically. Even if your code crashes inside the block. Even if an error happens. The file always gets closed.

Use with every time you work with files. It's the standard way.


Reading Line by Line

Sometimes you don't want the whole file as one string. You want each line separately.

with open("notes.txt", "r") as file:
    lines = file.readlines()

print(lines)
Enter fullscreen mode Exit fullscreen mode

Output:

['Alex\n', 'Priya\n', 'Sam\n', 'Jordan\n', 'Lisa\n']
Enter fullscreen mode Exit fullscreen mode

.readlines() gives you a list where each item is one line. But notice the \n at the end of each name. That's the newline character, the invisible marker that tells Python where one line ends and the next begins.

Strip it off with .strip().

with open("notes.txt", "r") as file:
    lines = file.readlines()

names = [line.strip() for line in lines]
print(names)
Enter fullscreen mode Exit fullscreen mode

Output:

['Alex', 'Priya', 'Sam', 'Jordan', 'Lisa']
Enter fullscreen mode Exit fullscreen mode

Clean list. No newline characters. This is the pattern you'll use constantly when loading data from text files.

Or loop directly through the file line by line, which is more memory-efficient for large files.

with open("notes.txt", "r") as file:
    for line in file:
        print(line.strip())
Enter fullscreen mode Exit fullscreen mode

Output:

Alex
Priya
Sam
Jordan
Lisa
Enter fullscreen mode Exit fullscreen mode

Writing to a File

with open("output.txt", "w") as file:
    file.write("Hello from Python\n")
    file.write("This is a second line\n")
    file.write("And a third\n")
Enter fullscreen mode Exit fullscreen mode

Run this. Check your folder. A new file called output.txt appeared with those three lines inside.

The "w" means write mode. Here is the dangerous part about "w". If output.txt already existed, Python deleted all its old content and started fresh. No warning. No confirmation. Just gone.

If you want to add to an existing file without destroying what's already there, use "a" for append mode.

with open("output.txt", "a") as file:
    file.write("This line gets added at the end\n")
Enter fullscreen mode Exit fullscreen mode

Run this a few times. Open the file. You'll see the new line added each time without losing the original content.


Writing Multiple Lines at Once

names = ["Alex", "Priya", "Sam", "Jordan"]

with open("names.txt", "w") as file:
    for name in names:
        file.write(name + "\n")
Enter fullscreen mode Exit fullscreen mode

Loop through a list, write each item as its own line. You'll use this shape when saving results, exporting data, logging outputs.


Working With JSON

Plain text files are useful but JSON is where things get interesting. JSON is a format for storing structured data, basically Python dictionaries and lists, saved as text.

import json

person = {
    "name": "Alex",
    "age": 25,
    "city": "Mumbai",
    "skills": ["Python", "Machine Learning", "SQL"]
}

with open("person.json", "w") as file:
    json.dump(person, file, indent=4)
Enter fullscreen mode Exit fullscreen mode

Open person.json in your editor. It looks like this:

{
    "name": "Alex",
    "age": 25,
    "city": "Mumbai",
    "skills": [
        "Python",
        "Machine Learning",
        "SQL"
    ]
}
Enter fullscreen mode Exit fullscreen mode

indent=4 makes it readable with nice formatting. Without it, everything is on one line.

Now read it back.

with open("person.json", "r") as file:
    data = json.load(file)

print(data["name"])
print(data["skills"])
Enter fullscreen mode Exit fullscreen mode

Output:

Alex
['Python', 'Machine Learning', 'SQL']
Enter fullscreen mode Exit fullscreen mode

json.dump() converts Python to JSON and saves it. json.load() reads JSON and converts it back to Python. The dictionary comes back exactly as you saved it.

This matters enormously in AI work. Model configurations are JSON. API responses are JSON. Dataset metadata is JSON. You'll read and write JSON constantly.


When the File Doesn't Exist

with open("missing.txt", "r") as file:
    content = file.read()
Enter fullscreen mode Exit fullscreen mode
FileNotFoundError: [Errno 2] No such file or directory: 'missing.txt'
Enter fullscreen mode Exit fullscreen mode

Your program crashes. Handle it properly.

try:
    with open("missing.txt", "r") as file:
        content = file.read()
    print(content)
except FileNotFoundError:
    print("That file doesn't exist.")
Enter fullscreen mode Exit fullscreen mode

Output:

That file doesn't exist.
Enter fullscreen mode Exit fullscreen mode

Program keeps running. You'll learn more about try/except in the next post. For now, just know this pattern exists and use it whenever opening a file that might not be there.


File Paths

So far you've used just a filename like "notes.txt". That works only when the file is in the same folder as your Python script.

For files in other locations, you need the full path.

# Windows
with open("C:\\Users\\Alex\\Documents\\data.txt", "r") as file:
    content = file.read()

# Mac and Linux
with open("/home/alex/documents/data.txt", "r") as file:
    content = file.read()
Enter fullscreen mode Exit fullscreen mode

The double backslash on Windows is because \ has special meaning in Python strings. You need \\ to mean a literal backslash. On Mac and Linux, forward slashes work fine.

A cleaner approach that works on all systems is using Python's pathlib module. But that's a more advanced topic. For now, keeping files in the same folder as your script keeps things simple.


Try This

Create files_practice.py.

Part one: write a list of at least eight cities to a file called cities.txt, one city per line.

Part two: read cities.txt back. Clean up the newline characters. Print how many cities are in the file.

Part three: create a dictionary with information about yourself, at least five keys. Save it to profile.json using json.dump. Then read it back and print each key and value on its own line.

Part four: try to open a file called doesnt_exist.txt and handle the error gracefully so the program prints a helpful message instead of crashing.


What's Next

Files can fail. Networks can fail. Users can type the wrong thing. Programs break in all kinds of ways. The next post is about handling errors properly so your code fails gracefully instead of crashing at the worst moment.

Top comments (0)