2009-03-31 12 views
2

J'écris un "hébergement de partage de fichiers" et je veux renommer tous les fichiers lors du téléchargement vers un nom unique et en quelque sorte garder une trace des noms sur la base de données. Puisque je ne veux pas que deux ou plusieurs fichiers aient le même nom (ce qui est sûrement impossible), je cherche un algorithme basé sur une clé ou quelque chose qui génère des noms aléatoires pour moi.Générer des noms de fichiers automatiquement sans collision

En outre, je ne souhaite pas générer de nom et rechercher dans la base de données pour voir si le fichier existe déjà. Je veux m'assurer 100% ou 99% que le nom de fichier généré n'a jamais été créé plus tôt par mon application.

Une idée de comment je peux écrire une telle application?

Répondre

10

Vous pouvez produire un hachage basé sur le contenu du fichier lui-même. Il y a deux bonnes raisons de le faire:

  1. Permet de ne jamais stocker le même fichier deux fois - par exemple, si vous avez deux copies d'un fichier de musique qui sont identiques dans le contenu que vous pouvez vérifier si vous avez déjà stocké ce fichier, et le stocker juste une fois.

  2. Vous séparer les méta-données (nom de fichier est seulement méta-données) à partir du blob. Donc, vous auriez un système de stockage qui est indexé par le hachage du contenu du fichier, et vous associez ensuite les méta-données du fichier avec ce code de recherche de hachage.

Le risque de trouver deux fichiers qui calculent le même hachage qui ne sont pas en effet le même contenu, en fonction de la taille du hachage serait faible, et vous pouvez atténuer efficacement que par le hachage peut-être le fichier morceaux (qui pourraient ensuite conduire à des scénarios d'optimisation de stockage intéressants: P).

+0

Assurez-vous de lire l'article suivant si vous allez faire quelque chose comme ceci: http://www.linuxworld.com/cgi-bin/mailto/x_linux.cgi?pagetosend=/export /home/httpd/linuxworld/news/2007/111207-hash.html –

+0

Y a-t-il une raison pour laquelle les systèmes de contrôle de source ne détectent pas de liaison dans ce dispositif? – ojblass

+0

Certains le font. Git nomme tous ses fichiers dans le dépôt interne après leurs hashes. –

3

GUIDs sont à sens unique. Vous êtes fondamentalement garanti de ne pas avoir de répétitions (si vous avez un générateur aléatoire approprié).

1

Le meilleur moyen est d'utiliser simplement un compteur. Le premier fichier est 1, le suivant est 2, un autre est 3, et ainsi de suite ...

Mais, il semble que vous voulez aléatoire. Pour le faire rapidement, vous pouvez vous assurer que votre nombre aléatoire est plus grand que le dernier fichier créé. Vous pouvez mettre en cache le dernier fichier, puis simplement compenser votre nombre aléatoire avec son nom de famille.

file = last_file + random(1 through 10) 
+0

+1, mais je pense que vous voulez "random (1 through 10)" - si vous avez un 0, vous allouer le même ID que la dernière fois. –

+0

oui, vous avez raison. J'ai édité votre suggestion dans. – carl

2

Vous pouvez également ajouter à l'heure depuis l'époque.

3

La meilleure solution a déjà été mentionnée. Je veux juste ajouter quelques pensées.

La solution la plus simple consiste à avoir un compteur et un incrément sur chaque nouveau fichier. Cela fonctionne très bien tant qu'un seul thread crée de nouveaux fichiers. Si plusieurs threads, processus ou même systèmes ajoutent de nouveaux fichiers, les choses deviennent un peu plus compliquées. Vous devez coordonner la création de nouveaux ID avec le verrouillage ou toute méthode de synchronisation similaire. Vous pouvez également affecter des plages d'identifiants à chaque processus pour réduire le travail de synchronisation ou étendre l'identificateur de fichier par un ID de processus unique.

Une meilleure solution pourrait être d'utiliser GUID dans ce scénario et ne pas avoir à se soucier de la synchronisation entre les processus. Enfin, vous pouvez à certaines données aléatoires à chaque identifiant pour les rendre plus difficile à deviner si cela est une exigence.

De même, coommon stocke des fichiers dans une structure de répertoires où l'emplacement d'un fichier dépend de son nom. Le fichier abcdef1234.xyz peut être stocké sous /ab/cd/ef/1234.xyz. Cela évite les répertoires avec un grand nombre de fichiers. Je ne sais pas vraiment pourquoi cela est fait - peut-être des limitations du système de fichiers, des problèmes de performance - mais c'est assez commun. Je ne sais pas si des choses similaires sont communes si les fichiers sont stockés directement dans la base de données.

Questions connexes