AI-agenter · Lektion

Sikre filoperationer med fejlhåndtering

Kontrol af filers eksistens og tilladelser samt hensynsfuld håndtering af IO-fejl.

Lektion 4 af 413 trin

Sikre filoperationer med fejlhåndtering er en gratis AI-agenter-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i AI-agenter, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. AI-agenter-kurset indeholder 4 lektioner i alt.

Hvorfor sikker filhåndtering er vigtig

Filhåndtering i agenter kan mislykkes på mange måder: filen findes ikke, agenten mangler tilladelse, stien er en mappe, eller der løber tør for diskplads under skrivningen. En agent, der går ned på grund af en filfejl, efterlader delvise resultater og en ødelagt tilstand. Defensiv programmering med korrekte kontroller og fejlhåndtering gør agenter robuste.

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 default

Path.exists() og Path.is_file()

Før du læser en fil, skal du kontrollere, at den findes og faktisk er en almindelig fil (ikke en mappe, et symbolsk link til en mappe eller en specialfil). Path.exists() returnerer True for alle filsystemobjekter; Path.is_file() returnerer kun True for almindelige filer.

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() — Kontrol af tilladelser

os.access(path, mode) kontrollerer, om den aktuelle proces har den angivne tilladelse til en fil. Brug os.R_OK til læsning, os.W_OK til skrivning og os.X_OK til kørsel. Det er nyttigt før forsøg på operationer, der kræver bestemte tilladelser.

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')

Håndtering af FileNotFoundError

FileNotFoundError (en underklasse af OSError) udløses, når du forsøger at åbne en fil, der ikke findes. Håndtér den eksplicit, og giv en nyttig fejlmeddelelse, der indeholder den forventede sti, så brugeren eller operatøren præcist ved, hvad der mangler.

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}')

Håndtering af PermissionError

PermissionError udløses, når processen mangler tilladelse til at læse eller skrive en fil. Det kan ske med systemfiler, filer der ejes af en anden bruger, eller filer med begrænsende tilladelser. Håndtér den altid separat fra FileNotFoundError — de kræver forskellige reaktioner.

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'))

Håndtering af IsADirectoryError

IsADirectoryError udløses, når du forsøger at åbne en mappe, som om den var en fil. Det kan ske, når en agent konstruerer en sti forkert — for eksempel ved at føje et filnavn til, som allerede findes som en mappe. Håndtér den altid, så du kan give en meningsfuld fejlmeddelelse.

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}')

Atomiske skrivninger med tempfile

Det er risikabelt at skrive direkte til en fil — hvis agenten går ned midt under skrivningen, bliver filen kun delvist skrevet og beskadiget. Løsningen er en atomisk skrivning: skriv først til en midlertidig fil, og omdøb den derefter til den endelige sti. Omdøbning er atomisk på POSIX-systemer — den endelige fil er enten den gamle version eller den nye, aldrig en delvis version.

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'))

Fillåsning for samtidige agenter

Når flere agentinstanser kører parallelt og skriver til den samme fil, kan kapløbsforhold ødelægge data. Brug fillåsning med modulet fcntl (Linux/macOS) eller biblioteket filelock på tværs af platforme for at forhindre samtidige skrivninger.

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 None

Sikker sletning med eksistenskontrol

Sletning af en fil, der ikke findes, udløser FileNotFoundError. Sletning af en mappe med Path.unlink() udløser IsADirectoryError. Brug Path.unlink(missing_ok=True) (Python 3.8+) eller kontrollér, om filen findes først, så sletningen bliver sikker.

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')

Kontrol af diskplads før skrivning

Agenter, der skriver store filer (AI-resultater, datasæt, logge), bør først kontrollere den tilgængelige diskplads. shutil.disk_usage(path) returnerer antal samlede, brugte og ledige byte. Kontrollér, at den ledige plads overstiger resultatets forventede størrelse, før du starter en langvarig skriveoperation.

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)

Sikkerhedskopi før overskrivning

Når en agent opdaterer en eksisterende fil, er det en god idé at gemme en sikkerhedskopi af den tidligere version. Det gør det muligt at rulle tilbage, hvis det nye indhold er forkert. Brug et tidsstemplet filnavn til sikkerhedskopien, og begræns antallet af sikkerhedskopier, så du undgår at fylde diskpladsen.

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.*'))])

Hurtig kontrol: Atomiske skrivninger

Kontrollér din forståelse af sikre mønstre til filskrivning.

Opsummering af sikre filoperationer

Dine agenter kan nu håndtere filer på en robust måde:

  • Kontrollér før adgang: Path.exists() + Path.is_file() + os.access(path, os.R_OK)
  • Håndtér FileNotFoundError, PermissionError og IsADirectoryError med tydelige fejlmeddelelser
  • Brug atomiske skrivninger (tempfile + os.replace) for at forhindre delvise eller beskadigede filer ved nedbrud
  • Brug fillåsning (filelock-biblioteket), når flere agenter skriver til den samme fil
  • Brug missing_ok=True til sikker sletning uden FileNotFoundError
  • Kontrollér diskplads før store skrivninger, og gem sikkerhedskopier, før vigtige filer overskrives
Gratis at komme i gang

Lær AI-agenter med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
60
Lektioner
239

Ofte stillede spørgsmål

Er lektionen “Sikre filoperationer med fejlhåndtering” gratis?

Ja — hele teksten til “Sikre filoperationer med fejlhåndtering” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af AI-agenter-kurset, skal du opgradere til CoddyKit PRO. AI-agenter-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Sikre filoperationer med fejlhåndtering”?

Kontrol af filers eksistens og tilladelser samt hensynsfuld håndtering af IO-fejl. Du øver dig i AI-agenter med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på AI-agenter?

Der kræves ingen tidligere erfaring. AI-agenter på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.

Hvor lang tid tager lektionen “Sikre filoperationer med fejlhåndtering”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne AI-agenter-lektion?

Ja. Alle AI-agenter-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Læsning og skrivning af filer i agentkontekst
  2. Gennemgang af mapper og filsøgning
  3. Håndtering af filformater: CSV, JSON og TXT
  4. Sikre filoperationer med fejlhåndtering
← Tilbage til AI-agenter