Python os.scandir() Method

Usage

While os.listdir() is sufficient for simple tasks like obtaining a list of names in a directory, it becomes inefficient for large directories, especially when you need to know the entry’s metadata, such as whether it is a directory or a file.

This is where the more advanced and memory-efficient os.scandir() function (introduced in Python 3.5) comes in.

Instead of plain filenames, os.scandir() returns an iterator of os.DirEntry objects for each entry in the directory. These objects include not only the filename but also information about the entry’s type (file, directory, etc.). More importantly, os.scandir() retrieves this metadata without additional system calls, resulting in significant performance improvements over os.listdir().

Syntax

import os entries = os.scandir(path=’.’)

Parameters

ParameterConditionDescription
pathOptionalA string representing the path of the directory whose contents you want to list.
Default value is ‘.’ (current working directory)

Return Value

os.scandir() returns an iterator of os.DirEntry objects for each entry (file or directory) in the specified directory.

os.DirEntry Object

os.DirEntry objects expose the following key attributes and methods, allowing you to gather information about each entry without making additional system calls:

  • name: Filename or directory name.
  • path: The full path to the file or directory.
  • is_file(): Returns True if the entry is a regular file, otherwise False.
  • is_dir(): Returns True if the entry is a directory, otherwise False.
  • Other methods include file type information, access times, and stat data (stat(), lstat(), and so on).

Basic Example

Here’s an example of using os.scandir() to list the contents of a directory:

import os

# Specify the directory path
path = '/path/to/directory'

# List all entries in the specified directory
entries = os.scandir(path)

# Print the entry names
for entry in entries:
    print(entry.name)

# Output:
# file1.txt
# folder1
# image.jpg

Distinguishing Files from Directories

To distinguish files from directories, you can use the is_file() and is_dir() methods provided by the os.DirEntry objects. These methods return True or False, depending on whether the entry is a file or a directory.

Here’s a simple example of how to use os.scandir() to iterate through all entries in a specified directory and distinguish between files and directories:

import os

# Specify the directory path
path = '/path/to/your/directory/'

# List all entries in the specified directory
entries = os.scandir(path)

for entry in entries:
    # Check if it's a file or directory
    if entry.is_file():
        print(f"{entry.name} is a file.")
    elif entry.is_dir():
        print(f"{entry.name} is a directory.")

# Output:
# file1.txt is a file.
# folder1 is a directory.
# image.jpg is a file.

Automatic Resource Cleanup with ‘with’

When using os.scandir() with a with statement, it automatically handles the opening and closing of the directory stream, ensuring that resources are freed up properly once the directory listing is no longer needed.

import os

# Using with statement with os.scandir() for efficient resource management
with os.scandir('/path/to/your/directory/') as entries:
    for entry in entries:
        if entry.is_file():
            print(f"{entry.name} is a file.")
        elif entry.is_dir():
            print(f"{entry.name} is a directory.")

# Output:
# file1.txt is a file.
# folder1 is a directory.
# image.jpg is a file.

Handling Exceptions

os.scandir() can raise exceptions, most commonly FileNotFoundError if the directory does not exist, PermissionError if access to the directory is denied, or OSError for other file system-related errors.

So it’s good practice to use exception handling (try-except blocks) to deal with these potential errors.

import os

# Specify the directory path
path = '/path/to/directory'

try:
    # Using with statement with os.scandir() for efficient resource management
    with os.scandir(path) as entries:
        for entry in entries:
            if entry.is_file():
                print(f"{entry.name} is a file.")
            elif entry.is_dir():
                print(f"{entry.name} is a directory.")

except FileNotFoundError:
    # Handle the case where the specified directory does not exist
    print(f"Error: The directory '{path}' does not exist.")

except PermissionError:
    # Handle the case where permission is denied
    print(f"Error: Permission denied to access the directory '{path}'.")

except OSError as error:
    # Handle other OS-related errors
    print(f"Error: An OS error occurred: {error}")