Opérations sûres sur les fichiers avec gestion des erreurs
Vérifiez l’existence et les permissions des fichiers, puis gérez les erreurs d’IO avec élégance.
Opérations sûres sur les fichiers avec gestion des erreurs est une leçon AI Agents gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Agents, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Agents comprend 4 leçons au total.
Pourquoi les opérations sûres sur les fichiers sont importantes
Les opérations sur les fichiers effectuées par les agents peuvent échouer de nombreuses façons : le fichier n’existe pas, l’agent ne dispose pas des autorisations nécessaires, le chemin désigne un répertoire ou l’espace disque est épuisé au milieu de l’écriture. Un agent qui plante à cause d’une erreur de fichier laisse une sortie partielle et un état corrompu. Une programmation défensive, avec des vérifications et une gestion appropriée des erreurs, rend les agents plus robustes.
from pathlib import Path
# Unsafe: crashes with FileNotFoundError
# content = Path('missing.txt').read_text()
# Safe: check first
path = Path('config.json')
if path.exists():
content = path.read_text(encoding='utf-8')
print('Loaded config')
else:
print(f'Config not found at {path.resolve()}')
content = '{}' # use defaultPath.exists() and Path.is_file()
Avant de lire un fichier, vérifiez qu’il existe et qu’il s’agit bien d’un fichier ordinaire (et non d’un répertoire, d’un lien symbolique vers un répertoire ou d’un fichier spécial). Path.exists() renvoie vrai pour tout objet du système de fichiers ; Path.is_file() renvoie vrai uniquement pour les fichiers ordinaires.
from pathlib import Path
path = Path('data/report.csv')
# Chain of checks
if not path.exists():
print(f'Not found: {path}')
elif not path.is_file():
print(f'Not a regular file: {path} (is_dir={path.is_dir()})')
elif path.stat().st_size == 0:
print(f'File is empty: {path}')
else:
# Safe to read
import csv
with open(path, 'r', encoding='utf-8', newline='') as f:
reader = csv.DictReader(f)
rows = list(reader)
print(f'Read {len(rows)} rows')os.access() — Vérification des permissions
os.access(path, mode) vérifie si le processus actuel dispose de la permission spécifiée sur un fichier. Utilisez os.R_OK pour la lecture, os.W_OK pour l’écriture et os.X_OK pour l’exécution. Cette fonction est utile avant d’entreprendre des opérations qui nécessitent des permissions spécifiques.
import os
from pathlib import Path
def check_file_access(path):
p = Path(path)
checks = {
'exists': p.exists(),
'is_file': p.is_file(),
'readable': os.access(p, os.R_OK),
'writable': os.access(p, os.W_OK),
}
for check, result in checks.items():
status = 'OK' if result else 'FAIL'
print(f' {check}: {status}')
return all(checks.values())
if check_file_access('data/input.json'):
print('File is accessible')
else:
print('Access problem — check path and permissions')Intercepter FileNotFoundError
FileNotFoundError (une sous-classe de OSError) est levée lorsque vous essayez d’ouvrir un fichier qui n’existe pas. Interceptez-la explicitement et fournissez un message d’erreur utile qui inclut le chemin attendu, afin que l’utilisateur ou l’opérateur sache exactement ce qui manque.
import json
from pathlib import Path
def load_agent_config(config_path='agent_config.json'):
path = Path(config_path)
try:
with open(path, 'r', encoding='utf-8') as f:
return json.load(f)
except FileNotFoundError:
print(f'Config file not found: {path.resolve()}')
print('Create agent_config.json with your settings')
print('Example: {"model": "gpt-4o", "max_retries": 3}')
return {} # return empty config as default
except json.JSONDecodeError as e:
print(f'Invalid JSON in {path}: {e}')
return {}
# --- demo ---
config = load_agent_config('does_not_exist_config.json')
print(f'Config used: {config}')
Intercepter PermissionError
PermissionError est levée lorsque le processus ne dispose pas de la permission de lire ou d’écrire dans un fichier. Cela peut se produire avec des fichiers système, des fichiers appartenant à un autre utilisateur ou des fichiers dont les permissions sont restrictives. Interceptez-la toujours séparément de FileNotFoundError : ces erreurs nécessitent des réponses différentes.
from pathlib import Path
def read_file_safely(path):
try:
return Path(path).read_text(encoding='utf-8')
except FileNotFoundError:
print(f'File not found: {path}')
return None
except PermissionError:
import os
print(f'Permission denied: {path}')
print(f'File permissions: {oct(Path(path).stat().st_mode)}')
print(f'Current user: {os.getlogin()}')
print('Try: chmod +r ' + str(path))
return None
except IsADirectoryError:
print(f'Path is a directory, not a file: {path}')
return None
# --- demo ---
import os
print(read_file_safely('does_not_exist.txt'))
os.makedirs('a_directory', exist_ok=True)
print(read_file_safely('a_directory'))
Intercepter IsADirectoryError
IsADirectoryError est levée lorsque vous essayez d’ouvrir un répertoire comme s’il s’agissait d’un fichier. Cela peut se produire lorsqu’un agent construit un chemin incorrectement, par exemple en ajoutant un nom de fichier qui existe déjà en tant que répertoire. Interceptez toujours cette erreur afin de produire un résultat d’erreur explicite.
from pathlib import Path
def safe_write(output_path, content):
path = Path(output_path)
# Check the path is not an existing directory
if path.is_dir():
raise IsADirectoryError(
f'Cannot write file: {path} is a directory. '
f'Use a filename like {path}/output.txt instead.'
)
# Ensure parent directory exists
path.parent.mkdir(parents=True, exist_ok=True)
try:
path.write_text(content, encoding='utf-8')
print(f'Written: {path} ({len(content)} chars)')
except IsADirectoryError as e:
print(f'Path error: {e}')
except PermissionError:
print(f'Cannot write to {path} — permission denied')
# --- demo ---
import os
safe_write('demo_output/report.txt', 'Agent finished the task.')
os.makedirs('already_a_dir', exist_ok=True)
try:
safe_write('already_a_dir', 'this will fail')
except IsADirectoryError as e:
print(f'Rejected: {e}')
Écritures atomiques avec des fichiers temporaires
Écrire directement dans un fichier est dangereux : si l’agent s’arrête brutalement en cours d’écriture, le fichier reste partiellement écrit et est corrompu. La solution consiste en une écriture atomique : écrivez d’abord dans un fichier temporaire, puis renommez-le avec le chemin final. Le renommage est atomique sur les systèmes POSIX : le fichier final correspond soit à l’ancienne version, soit à la nouvelle, jamais à une version partielle.
import tempfile
import os
import json
from pathlib import Path
def atomic_write_json(file_path, data):
path = Path(file_path)
path.parent.mkdir(parents=True, exist_ok=True)
# Write to temp file in same directory
tmp_fd, tmp_path = tempfile.mkstemp(
dir=path.parent,
prefix='.tmp_',
suffix='.json'
)
try:
with os.fdopen(tmp_fd, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=2, ensure_ascii=False)
# Atomic rename: replaces final file in one operation
os.replace(tmp_path, path)
print(f'Atomically wrote: {path}')
except Exception as e:
os.unlink(tmp_path) # clean up temp file on error
raise
# --- demo ---
atomic_write_json('demo_state/state.json', {'step': 3, 'status': 'running'})
print('File contents:', Path('demo_state/state.json').read_text(encoding='utf-8'))
Verrouillage de fichiers pour les agents concurrents
Lorsque plusieurs instances d’agent s’exécutent en parallèle et écrivent dans le même fichier, les conditions de concurrence corrompent les données. Utilisez le verrouillage de fichiers avec le module fcntl (Linux/macOS) ou la bibliothèque multiplateforme filelock pour empêcher les écritures concurrentes.
from filelock import FileLock, Timeout
import json
from pathlib import Path
COUNTER_FILE = Path('shared_counter.json')
LOCK_FILE = Path('shared_counter.json.lock')
def increment_counter():
lock = FileLock(str(LOCK_FILE), timeout=10)
try:
with lock:
# Only one process can be here at a time
if COUNTER_FILE.exists():
data = json.loads(COUNTER_FILE.read_text())
else:
data = {'count': 0}
data['count'] += 1
COUNTER_FILE.write_text(
json.dumps(data, indent=2)
)
return data['count']
except Timeout:
print('Could not acquire lock within 10 seconds')
return NoneSuppression sécurisée avec vérification de l’existence
Supprimer un fichier inexistant lève FileNotFoundError. Supprimer un répertoire avec Path.unlink() lève IsADirectoryError. Utilisez Path.unlink(missing_ok=True) (Python 3.8 ou version ultérieure) ou vérifiez d’abord l’existence du fichier pour effectuer une suppression sûre.
from pathlib import Path
import shutil
# Safe file deletion (Python 3.8+)
Path('temp_output.json').unlink(missing_ok=True)
# Safe directory deletion
def safe_remove(path):
p = Path(path)
if not p.exists():
print(f'Already gone: {p}')
return
if p.is_file():
p.unlink()
print(f'Deleted file: {p}')
elif p.is_dir():
shutil.rmtree(p)
print(f'Deleted directory: {p}')
else:
print(f'Unknown file type: {p}')
# Clean up temporary workspace
safe_remove('/tmp/agent_workspace/run_001')Vérification de l’espace disque avant l’écriture
Les agents qui écrivent de gros fichiers (sorties d’IA, jeux de données, journaux) doivent d’abord vérifier l’espace disque disponible. shutil.disk_usage(path) renvoie le nombre total d’octets, le nombre d’octets utilisés et le nombre d’octets libres. Vérifiez que l’espace libre dépasse la taille de sortie prévue avant de commencer une longue opération d’écriture.
import shutil
from pathlib import Path
def check_disk_space(output_dir, required_bytes):
path = Path(output_dir)
path.mkdir(parents=True, exist_ok=True)
usage = shutil.disk_usage(path)
free_gb = usage.free / (1024 ** 3)
required_gb = required_bytes / (1024 ** 3)
print(f'Disk free: {free_gb:.2f} GB')
print(f'Required: {required_gb:.2f} GB')
if usage.free < required_bytes * 1.1: # 10% safety margin
raise IOError(
f'Insufficient disk space: '
f'{free_gb:.2f} GB free, '
f'{required_gb:.2f} GB required'
)
return True
# Before writing a 500 MB dataset
check_disk_space('/tmp/output', 500 * 1024 * 1024)Sauvegarde avant remplacement
Lorsqu’un agent met à jour un fichier existant, il est prudent de conserver une sauvegarde de la version précédente. Vous pourrez ainsi revenir en arrière si le nouveau contenu est incorrect. Utilisez un nom de fichier de sauvegarde horodaté et limitez le nombre de sauvegardes pour éviter de remplir l’espace disque.
import shutil
import datetime
from pathlib import Path
def write_with_backup(file_path, content, max_backups=5):
path = Path(file_path)
backup_dir = path.parent / '.backups'
backup_dir.mkdir(exist_ok=True)
# Backup existing file
if path.exists():
timestamp = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')
backup = backup_dir / f'{path.name}.{timestamp}'
shutil.copy2(path, backup)
print(f'Backed up to: {backup}')
# Write new content
path.write_text(content, encoding='utf-8')
# Prune old backups
backups = sorted(backup_dir.glob(f'{path.name}.*'))
for old in backups[:-max_backups]:
old.unlink()
print(f'Pruned old backup: {old.name}')
# --- demo ---
write_with_backup('demo_notes.txt', 'version 1')
write_with_backup('demo_notes.txt', 'version 2')
print('Backups:', [p.name for p in sorted(Path('.backups').glob('demo_notes.txt.*'))])
Vérification rapide : écritures atomiques
Vérifiez votre compréhension des méthodes d’écriture sécurisée de fichiers.
Récapitulatif des opérations sécurisées sur les fichiers
Vos agents peuvent maintenant gérer les fichiers de manière défensive :
- Vérifier avant l’accès :
Path.exists()+Path.is_file()+os.access(path, os.R_OK) - Intercepter FileNotFoundError, PermissionError et IsADirectoryError avec des messages clairs
- Utiliser des écritures atomiques (tempfile + os.replace) pour éviter les fichiers partiels ou corrompus en cas d’arrêt brutal
- Utiliser le verrouillage de fichiers (bibliothèque filelock) lorsque plusieurs agents écrivent dans le même fichier
- Utiliser missing_ok=True pour supprimer des fichiers sans risque de FileNotFoundError
- Vérifier l’espace disque avant les écritures volumineuses et conserver des sauvegardes avant de remplacer des fichiers importants
Apprends AI Agents avec un tuteur IA — gratuit
Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.
- Cours
- 60
- Leçons
- 239
Questions Fréquemment Posées
La leçon « Opérations sûres sur les fichiers avec gestion des erreurs » est-elle gratuite ?
Oui — le texte complet de « Opérations sûres sur les fichiers avec gestion des erreurs » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Agents, passe à CoddyKit PRO. Le cours AI Agents comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Opérations sûres sur les fichiers avec gestion des erreurs » ?
Vérifiez l’existence et les permissions des fichiers, puis gérez les erreurs d’IO avec élégance. Tu pratiques AI Agents avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer AI Agents ?
Aucune expérience préalable n'est requise. AI Agents sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Opérations sûres sur les fichiers avec gestion des erreurs » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon AI Agents ?
Oui. Chaque leçon AI Agents inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Lire et écrire des fichiers dans le contexte d’un agent
- Parcours des répertoires et découverte de fichiers
- Gestion des formats de fichiers : CSV, JSON et TXT
- Opérations sûres sur les fichiers avec gestion des erreurs