How to open a file for both reading and writing?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Opening a file for both reading and writing means choosing a mode that allows the program to inspect existing content and then modify the same file handle. In Python, the main modes for this are r+, w+, and a+, and the important difference between them is what happens to the file when you open it.
Choose the Right File Mode
The three most useful read-write modes are:
- '
r+for reading and writing without truncating' - '
w+for reading and writing after truncating the file' - '
a+for reading and appending'
They are similar enough to be confusing, so the file-opening decision should happen before you write any code that touches the file contents.
Use r+ When the File Must Already Exist
r+ opens a file for both reading and writing, but it does not create the file. It also keeps the existing contents.
This example reads the entire file, moves the file pointer back to the beginning with seek(0), writes updated content, and then truncates the file so old leftover bytes do not remain at the end.
That last step matters whenever the new content may be shorter than the original.
Use w+ When You Want a Fresh File
w+ is more destructive. It opens the file for reading and writing, creates it if needed, and truncates it immediately.
This mode is correct when you intentionally want to replace the entire file. It is the wrong choice if you needed the old data, because that data is erased as soon as the file opens.
Use a+ for Read and Append Workflows
a+ keeps existing content and creates the file if it does not exist, but writes always go to the end of the file.
This is useful for log-like files or journals where updates should be appended rather than inserted in the middle.
File Pointer Position Is a Big Part of the Problem
Many read-write bugs are really pointer-position bugs. After a read(), the pointer is at the end of the file. After a write() in append mode, it is still effectively treated as an append position for later writes.
That is why seek() shows up so often in correct examples. If you want to read again from the start, call file.seek(0). If you want to overwrite a specific region, move the pointer first.
Binary Variants Work the Same Way
If the file contains bytes rather than text, add b to the mode:
- '
rb+' - '
wb+' - '
ab+'
The semantics stay the same, but the file object reads and writes bytes instead of strings.
Common Pitfalls
The biggest pitfall is using w+ when you meant r+. w+ truncates the file immediately, so the original contents are gone before your logic even runs.
Another common issue is forgetting seek(0) before rereading or overwriting. The file pointer does not reset automatically.
People also forget truncate() after rewriting shorter content. Without it, stale bytes from the original file may remain at the end.
Finally, remember that r+ requires the file to exist already. If you want a mode that creates the file when missing, use w+ or a+ depending on the intended behavior.
Summary
- Use
r+to read and write without truncating an existing file. - Use
w+to start fresh, knowing that it erases old contents immediately. - Use
a+when you need to read the file and append new data to the end. - Manage the file pointer explicitly with
seek()during mixed read-write workflows. - Call
truncate()after overwriting shorter content so stale bytes are removed.

