Python aiofiles: Read & Write files asynchronously

Updated: January 6, 2024 By: Guest Contributor Post a comment

Introduction

Python’s aiofiles module enables asynchronous file handling, allowing for non-blocking I/O operations that are essential for writing high-performance asynchronous applications.

Getting Started with aiofiles

To begin using aiofiles, you must first install the package using pip:

pip install aiofiles

Basic Asynchronous File Reading

The following snippet demonstrates how to open and read a file asynchronously:

import aiofiles
import asyncio

async def read_file(file_name):
    async with aiofiles.open(file_name, 'r') as f:
        contents = await f.read()
        print(contents)

asyncio.run(read_file('example.txt'))

Basic Asynchronous File Writing

Writing to a file asynchronously is just as straightforward:

async def write_file(file_name, text):
    async with aiofiles.open(file_name, 'w') as f:
        await f.write(text)

asyncio.run(write_file('example.txt', 'Hello, aiofiles!'))

Performing Complex Asynchronous File Operations

Beyond basic reading and writing, aiofiles offers capabilities for more complex operations:

Reading Files Line by Line

async def read_lines(file_name):
    async with aiofiles.open(file_name, 'r') as f:
        async for line in f:
            print(line.strip())

asyncio.run(read_lines('example.txt'))

Writing Multiple Lines Asynchronously

async def write_lines(file_name, lines):
    async with aiofiles.open(file_name, 'w') as f:
        await f.writelines(lines)

lines_to_write = ['First line\n', 'Second line\n', 'Third line']
asyncio.run(write_lines('example.txt', lines_to_write))

Advanced Asynchronous File Handling Techniques

Now let’s explore more advanced techniques for asynchronous file I/O.

Working with Binary Files

aiofiles also supports binary file operations:

async def read_binary_file(file_name):
    async with aiofiles.open(file_name, 'rb') as f:
        binary_content = await f.read()

async def write_binary_file(file_name, binary_data):
    async with aiofiles.open(file_name, 'wb') as f:
        await f.write(binary_data)

Using File Context Manager

If you prefer the context manager approach, aiofiles has you covered:

async def file_context_manager(file_name, text):
    async with aiofiles.open(file_name, mode='w') as f:
        await f.write(text)

Error Handling in Asynchronous File Operations

It’s important to handle possible errors that may occur during asynchronous file I/O:

async def safe_read_file(file_name):
    try:
        async with aiofiles.open(file_name, 'r') as f:
            contents = await f.read()
    except FileNotFoundError:
        print(f'The file {file_name} was not found.')
    except Exception as e:
        print(f'An error occurred: {e}')

Combining aiofiles with Other Asynchronous Libraries

aiofiles can efficiently work in conjunction with other asynchronous libraries, like aiohttp for handling HTTP requests and responses.

Downloading and Saving a File Asynchronously

import aiohttp

async def download_and_save(url, file_name):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            if response.status == 200:
                async with aiofiles.open(file_name, 'wb') as f:
                    while True:
                        chunk = await response.content.read(1024)
                        if not chunk:
                            break
                        await f.write(chunk)

See also:

Conclusion

Asynchronous file I/O with aiofiles in Python simplifies the development of high-performance applications by allowing concurrent I/O operations. This tutorial sought to provide insights into its basic usage, error handling, and integration with other asynchronous tasks, demonstrating its versatility and power.