HOWTO · Python
How to Open All the Files in a Directory in Python
Read files in one directory with os.listdir(), select matches with glob.glob(), scan entries with os.scandir(), or include nested directories with os.walk().
On this page
To read text files in a directory, use os.listdir() for a single directory, glob.glob() to select names by a pattern, os.scandir() to inspect entries, or os.walk() to include nested directories. Build paths with the returned names and use open() in a with statement. These examples read text; binary files need binary mode such as "rb" or a format-specific parser.
Open files in a directory with os.walk()
Use os.walk() when files may be in the starting directory or any directory below it. On each iteration it yields three values: the current directory path (root), names of its child directories (dirnames), and names of files directly in that directory (filenames). Join root and each filename to get a path; joining only the starting directory and filename would miss files in nested directories.
This example creates a small directory tree so it can run as written. Sorting the directory and file names makes the processing order predictable for this fixture; directory traversal order is otherwise not guaranteed.
Run this example:
import os
import tempfile
with tempfile.TemporaryDirectory() as directory:
nested = os.path.join(directory, "notes")
os.mkdir(nested)
for folder, name, contents in [
(directory, "summary.txt", "Ready"),
(nested, "details.txt", "More notes"),
]:
with open(os.path.join(folder, name), "w", encoding="utf-8") as file:
file.write(contents)
for root, dirnames, filenames in os.walk(directory):
dirnames.sort()
for filename in sorted(filenames):
path = os.path.join(root, filename)
with open(path, encoding="utf-8") as file:
print(f"{filename}: {file.read()}")
os.walk() can traverse top-down or bottom-up. The default is top-down, which is suitable when processing files as they are found. The example explicitly uses UTF-8; choose an encoding that matches your text files. If files use different encodings, handle those files according to the format rather than assuming one encoding works for all of them. For directories your process cannot read, handle the resulting filesystem errors according to the needs of your application.
Open files in a directory with os.listdir()
os.listdir() returns the names of entries directly inside one directory. It does not descend into child directories, and its result can include both files and directories. Join each name to the directory path and check os.path.isfile() before opening it, as shown below.
import os
import tempfile
with tempfile.TemporaryDirectory() as directory:
with open(os.path.join(directory, "one.txt"), "w", encoding="utf-8") as file:
file.write("First file")
os.mkdir(os.path.join(directory, "archive"))
for name in sorted(os.listdir(directory)):
path = os.path.join(directory, name)
if os.path.isfile(path):
with open(path, encoding="utf-8") as file:
print(f"{name}: {file.read()}")
This approach is useful when you want every regular file in one directory and do not need pattern matching. The os.path.isfile() check follows symbolic links to files; if your application must distinguish links or apply a different policy, use the appropriate path or directory-entry checks. Keep the with block around each file so Python closes it after the read, including if later processing exits that block early.
Open matching files with glob.glob()
glob.glob() selects paths using a filename pattern. A pattern such as *.txt matches text files directly in the named directory; it does not search child directories by itself. The returned paths can be passed to open() directly. Use os.walk() when the task is to visit a whole tree, or build a recursive pattern deliberately if that is what you need.
import glob
import os
import tempfile
with tempfile.TemporaryDirectory() as directory:
for name, contents in [("readme.txt", "Instructions"), ("data.csv", "id")]:
with open(os.path.join(directory, name), "w", encoding="utf-8") as file:
file.write(contents)
pattern = os.path.join(directory, "*.txt")
for path in sorted(glob.glob(pattern)):
with open(path, encoding="utf-8") as file:
print(f"{os.path.basename(path)}: {file.read()}")
Change the final pattern component to select a different set of filenames, such as report-*.csv. Sorting the matches is useful when later work depends on a stable order. A pattern can match directory names too, so filter matching paths with os.path.isfile() if the pattern is not limited to files.
Open files in a directory with os.scandir()
os.scandir() yields directory-entry objects that expose each entry’s name and path and provide methods such as is_file(). It is useful when the loop needs to check an entry before opening it or inspect entry information. The iterator is a context manager, so use with to close it when iteration finishes. This example checks entries and reads regular files; it does not recurse into child directories.
import os
import tempfile
with tempfile.TemporaryDirectory() as directory:
with open(os.path.join(directory, "notes.txt"), "w", encoding="utf-8") as file:
file.write("Scanned text")
os.mkdir(os.path.join(directory, "archive"))
with os.scandir(directory) as entries:
for entry in sorted(entries, key=lambda item: item.name):
if entry.is_file():
with open(entry.path, encoding="utf-8") as file:
print(f"{entry.name}: {file.read()}")
entry.name is the name within the scanned directory, while entry.path is the path to use when opening that entry. Like os.listdir(), a single os.scandir() call covers one directory only. If entries may change between checking and opening, filesystem state can change during that interval, so code that handles untrusted or concurrently modified directories should account for open-time errors as well.
Choose the right method for your directory
Choose os.listdir() for a straightforward, nonrecursive pass over one directory. Choose glob.glob() when a filename pattern should decide which paths to process. Choose os.walk() when files in nested directories are part of the task. Choose os.scandir() when each entry needs a file check or other entry information before you act on it.
All four methods enumerate directory contents, but enumeration order is not guaranteed; sort names or paths when repeatable processing matters. The examples use context-managed file objects and UTF-8 text mode. Adapt the encoding to the source files, and use binary mode or a parser when the files are not plain text. Access permissions, files disappearing during processing, and application-specific encoding differences may require additional handling in production code.