Tester si un dossier contient déjà l'empreinte d'un fichier

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Salut à tous !

J'aimerais créer en Python une fonction qui m'indique si un fichier existe déjà dans un dossier en comparant leurs empreintes (et pas leurs noms).

J'ai pensé à faire un vulgaire for ou while qui compare l’empreinte md5 des fichiers, mais je suis sur qu'il y a plus optimisé en Python, c'est pourquoi je fais appel à vous ;)

Je vous remercie par avance.

+0 -0
Staff

Cette réponse a aidé l'auteur du sujet

Bah tu va pas avoir beaucoup d'autres choix que de calculer l'empreinte de ton fichier et de la comparer à celle de tous les fichiers. Par contre avec des itérateurs tu dois pouvoir t’arrêter facilement dès que le fichier est trouvé

Tu dois pouvoir faire un truc comme ça :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import hashlib
from os import listdir
from os.path import isfile, join

def hash_file(path):
    return hashlib.md5(open(path, 'rb').read()).hexdigest()

def file_present(file_path, dir_path):
     h_file = hash_file(file_path)
     dir_content = (join(dir_path,f) for f in listdir(dir_path))
     return any(hash_file(f) == h_file for f in dir_content if isfile(f))

C'est tellement rapide a faire (et dépendant de ta fonction de comparaison), que je ne suis pas surs qu'uil y ai un truc tout fait dans la lib standard pour ça.

edit: Tu peux probablement gagner un peu de temps en comparant tout d’abord la taille des fichier avant le hash car la taille est un élément fort discriminant des fichiers tout en étant rapide à obtenir (plus rapide que calculer un hash en tout cas). En gros ne comparer le hash que si les fichiers sont de taille identique. Mais bon ça dépend beaucoup de ton cas d'utilisation car cette solution est largement la plus simple et relativement rapide.

Par contre ici j'ai considéré que tu ne cherchais pas dans les sous dossier. Si tu veux rechercher dans les sous-dossier, il faut utiliser os.walk en lieu et place de listdir

Édité par Kje

+2 -0
Auteur du sujet

(encore)Merci,

ça fonctionne plutôt bien, et c'est plutôt rapide.

Penses tu que le md5 soit la méthode de hash la plus rapide ?

J'ai besoin d'optimiser cette méthode au maximum, car elle sert sur un serveur web Django lorsque l'utilisateur upload une image. Ça me permet d'éviter les doublons et d'économiser de la mémoire …

Édité par DigitalSuricate

+0 -0
Staff

Penses tu que le md5 soit la méthode de hash la plus rapide ?

Test ! A la ligne 6 tu as juste à changer md5 par md5, sha1, sha224, sha256, sha384 ou sha512 et tu verra.

Pour le reste je ne pense pas que ce soit très pertinent. Ça dépend beaucoup de ton appli mais l'upload est rarement une des fonctionnalité les plus utilisé. Si tous les utilisateurs uploads tous des images, là comparer la taille avant serait probablement plus efficace. Ou éventuellement avec les hash des fichiers actuellement existant déjà en mémoire (ou en base) pour éviter de les re-calculer.

Pour autant, méfie toi. Si tu met tout dans le même dossier, au bout d'un moment ça va devenir assez long à parcourir.

+1 -0
Auteur du sujet

Pour autant, méfie toi. Si tu met tout dans le même dossier, au bout d'un moment ça va devenir assez long à parcourir.

Kje

Oui je met toutes mes images dans le même dossier.

Je me demande comment font les "gros" sites pour gérer une grosse quantité d'images (comme les hébergeurs d'images, ou tout simplement facebook) ?

Les seuls optimisations que j'ai trouvé, c'est de rajouter un uuid aux noms des fichiers pour éviter les collisions de nom et de vérifier si il y a des fichiers en double.

Ou éventuellement avec les hash des fichiers actuellement existant déjà en mémoire (ou en base) pour éviter de les re-calculer.

Kje

je vais voir si je peux optimiser ça avec l'utilisation d'une bdd …

Édité par DigitalSuricate

+0 -0
Staff

Oui je met toutes mes images dans le même dossier. Je me demande comment font les "gros" sites pour gérer une grosse quantité d'images (comme les hébergeurs d'images, ou tout simplement facebook) ?

Ils s'embêtent pas. Il génèrent un uuid unique pour chaque upload et le mettent quelque part sur le cloud. Facebook balancent tout sur amazon il me semble par exemple. Le Go ne coute pas très cher, c'est plus simple de tout stoker avec un identifiant unique sans se préoccuper si il y a des images identiques.

+1 -0
Auteur du sujet

Hum, c'est bon à savoir ça. Donc si j'ai bien compris, par exemple si il y a 20 million d'utilisateurs qui upload la même image "Je suis Charlie", la même image sera stockée 20 million de fois ? :o

Les datacenters ne sont pas près de fermer :D (les écolos doivent être ravis)

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte