Déduplication des fichiers uploadés : référencer l'existant si même taille + même hash #49

Closed
opened 2026-05-13 11:30:10 +00:00 by cedricAbonnel · 1 comment
Owner

Problème

Chaque upload crée une copie physique du fichier dans data/{uuid}/files/, même si un fichier identique (même contenu) existe déjà dans un autre article. Résultat : espace disque gaspillé, fichiers dupliqués.

Comportement attendu

Lors d'un upload, si un fichier de même hash SHA-256 et même taille existe déjà dans data/*/files/, ne pas stocker de copie supplémentaire : référencer le fichier existant et supprimer le temporaire uploadé.

Contexte technique

Images — naming déjà hash-based

addFile() dans src/ArticleManager.php génère déjà {hash16}-{size}.{ext} pour les images. La détection d'un doublon se réduit à vérifier si ce nom existe dans un autre article :

$existing = glob($this->dataDir . '/*/files/' . $name);
if (!empty($existing)) {
    link($existing[0], $dest) || copy($existing[0], $dest);
    return $name;
}

Pas de recalcul de hash nécessaire — le nom est la clé.

Fichiers non-image

Le nom est basé sur le nom d'origine (sanitisé), pas sur le hash. Options :

  • calculer le hash SHA-256 et scanner les fichiers existants ;
  • ou limiter la déduplication aux images en phase 1.

Approche suggérée

  1. Phase 1 : images uniquement — glob sur {hash}-{size}.ext, hard link si trouvé, fallback copy() si filesystems différents.
  2. Phase 2 : non-images via hash calculé à l'upload.

Fichier concerné

app/src/ArticleManager.php — méthode addFile() (~ligne 776)

Notes

  • Hard link préférable au symlink : résistant aux déplacements, transparent à la lecture.
  • Ne pas modifier le comportement quand aucun doublon n'est trouvé.
## Problème Chaque upload crée une copie physique du fichier dans `data/{uuid}/files/`, même si un fichier identique (même contenu) existe déjà dans un autre article. Résultat : espace disque gaspillé, fichiers dupliqués. ## Comportement attendu Lors d'un upload, si un fichier de **même hash SHA-256 et même taille** existe déjà dans `data/*/files/`, ne pas stocker de copie supplémentaire : référencer le fichier existant et supprimer le temporaire uploadé. ## Contexte technique ### Images — naming déjà hash-based `addFile()` dans `src/ArticleManager.php` génère déjà `{hash16}-{size}.{ext}` pour les images. La détection d'un doublon se réduit à vérifier si ce nom existe dans un autre article : ```php $existing = glob($this->dataDir . '/*/files/' . $name); if (!empty($existing)) { link($existing[0], $dest) || copy($existing[0], $dest); return $name; } ``` Pas de recalcul de hash nécessaire — le nom est la clé. ### Fichiers non-image Le nom est basé sur le nom d'origine (sanitisé), pas sur le hash. Options : - calculer le hash SHA-256 et scanner les fichiers existants ; - ou limiter la déduplication aux images en phase 1. ## Approche suggérée 1. **Phase 1** : images uniquement — glob sur `{hash}-{size}.ext`, hard link si trouvé, fallback `copy()` si filesystems différents. 2. **Phase 2** : non-images via hash calculé à l'upload. ## Fichier concerné `app/src/ArticleManager.php` — méthode `addFile()` (~ligne 776) ## Notes - Hard link préférable au symlink : résistant aux déplacements, transparent à la lecture. - Ne pas modifier le comportement quand aucun doublon n'est trouvé.
Author
Owner

Ticket migré vers le dépôt Folio : cedricAbonnel/folio#35

Ticket migré vers le dépôt Folio : https://git.abonnel.fr/cedricAbonnel/folio/issues/35
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: cedricAbonnel/varlog#49