Rozdział 15 · Python i akta

Bezpieczne zarządzanie plikami

Zapisywanie do pliku to działanie z konsekwencjami. Rozsądna ostrożność jest warta kilku dodatkowych linijek kodu.

Przed nagraniem – zadaj sobie pytanie

  1. Czy chcę zastąpić treść, czy nadpisać?
  2. Albo utworzyć tylko, jeśli plik jeszcze nie istnieje?
  3. Czy potrzebuję zapasowego przed zmianą?
  4. Czy to dokładnie ta ścieżka, którą mam na myśli?"
Mode to świadomy wybór, a nie zalążek z przykładu
"r", "w", "a", "x" - Każdy z nich ma inne konsekwencje dla istniejących treści (Rozdział 15.15). Kopiowanie trybu z przykładu bez pytania „czego dokładnie teraz potrzebuję?”

Praktyka w tym kursie są wyłącznie w piaskownicach

Obowiązkowa zasada bezpieczeństwa w praktykach
Wszystkie praktyki związane z plikami w tym kursie czytają, tworzą, modyfikują i usuwają pliki tylko w swoim własnym folderze roboczym. Nigdy — pliki repozytorium kursu, dokumenty, które już zapisałeś, folder domowy użytkownika ani dowolne ścieżki bezwzględne. Dotyczy to również Twoich własnych programów: nie wykonuj operacji destrukcyjnych na ścieżce, która przyszła z zewnątrz, bez jej sprawdzenia.

Wyjście z twojego folderu jest path traversal

put_naruzhu.py
imya_fajla = input(„Nazwa pliku do zapisu: ”)
# jeśli użytkownik wpisze „.. /.. /important.txt”
path = Path("data") / imya_fajla
Naiwne łączenie ścieżki wiąże się z ryzykiem wyjścia poza folder
Jeśli nazwa pliku pochodzi od użytkownika i zawiera .., samo połączenie z bazowym folderem może przenieść cię poza niego, do zupełnie innego miejsca w systemie plików. Nie budujemy tu pełnego filtra bezpieczeństwa — ważne jest po prostu, by być świadomym samego ryzyka i nie ufać nazwie pliku użytkownika jako bezpiecznej.

Bardziej profesjonalne: Bezpieczne oszczędzanie

Pomysł na zmniejszenie ryzyka pozostawienia głównego pliku w uszkodzonym stanie pośrednim: Najpierw zapisz w tymczasowy plik w tym samym folderze, a następnie zastąp główny plik w całości:

bezopasnoe_sohranenie.py
import json
from pathlib import Path

def bezopasno_sohranit(path: Path, data: dict) -> None:
    vremenny = path.with_suffix(path.suffix + ".tmp")
    with vremenny.open("w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)
    vremenny.replace(path)   # zamień główny plik tylko wtedy, gdy wszystko jest już zapisane
Nie absolutna gwarancja — a zmniejszone ryzyko
Zmniejsza ryzyko odejścia path w częściowo zapisanym stanie przy przerwaniu zapisu, ale nie jest absolutną gwarancją bezpieczeństwa danych na jakimkolwiek sprzęcie i dowolnym systemie plików.

Kopia zapasowa przed wymianą

backup_pered_zamenoj.py
import shutil
from pathlib import Path

path = Path("save.json")
if path.exists():
    shutil.copy(path, path.with_suffix(".json.bak"))
Jedna kopia zapasowa, nie nieskończony łańcuch
Jedna aktualna kopia zapasowa przed wymianą zwykle wystarcza do zadań edukacyjnych i małych zastosowań — nie trzeba tworzyć nieskończenie rosnącego łańcucha plików .bak.bak.bak.
Praktyka: bezpieczne zapisywanie i kopia zapasowa
interaktywny laptop bezpośrednio w przeglądarce – Python 3.14 przez Pyodide, bez instalacji
Otwórz praktykę →