Qual è la migliore pratica per nominare le immagini caricate?


15

Supponiamo di avere un modulo nella mia applicazione Web in cui gli utenti possono caricare un'immagine del profilo.

Ho alcuni requisiti su dimensioni del file, dimensioni ecc., Ma quando l'utente carica l'immagine, come devo nominarli sul mio sistema? Suppongo che dovrebbe essere coerente e anche unico.

Forse un GUID?

a5c627bedc3c44b7ae7c06a44fb3fcf8.jpg

Un timestamp?

129899740140465735.jpg

Un hash? Es: md5

b1a9acaf295cf14ffbc5b6538294562c.jpg

Esiste un modo standard o consigliato per farlo?


7
Se il tuo obiettivo è quello di memorizzare solo una foto del profilo per utente, alcuni direbbero che la scelta ovvia sarebbe nominare il file come l'id utente.
Alan Barber,

il timestamp non è una buona idea, perché DateTime.Now viene aggiornato solo ogni 15ms. Esiste un'alta probabilità di collisione, ad esempio durante il caricamento di massa, le richieste in coda, ecc.
jhexp

Risposte:


27

Dovresti cercare di raggiungere due obiettivi: unicità e utilità.

L'uso di un GUID garantisce l'univocità, ma un giorno i file potrebbero staccarsi dalla loro fonte originale e quindi potresti avere problemi.

La mia soluzione tipica è quella di incorporare informazioni cruciali nel nome del file, come ID utente (se appartiene a un utente) o la data e l'ora caricate (se questo è significativo), o il nome file utilizzato durante il caricamento.

Questo potrebbe davvero salvare la tua pelle un giorno, quando le informazioni incorporate nel nome file ti consentono, ad esempio, di recuperare da un bug o l'eliminazione accidentale dei record. Se tutto ciò che hai sono GUID e perdi il catalogo, avrai un gran bel lavoro da ripulire.

Ad esempio, se un file "My Holiday: Florida 23.jpg" viene caricato, dall'utente ID 98765, il 2013/04/04 alle 12:51:23, lo nominerei in questo modo, aggiungendo una stringa casuale ad8a7dsf9:

20130404125123-ad8a7dsf9-98765-my-vacanza-florida-23.jpg

  • L'unicità è garantita dalla data e ora e dalla stringa casuale (a condizione che sia propriamente casuale da / dev / urandom o CryptGenRandom.
  • Se il file viene mai rimosso, è possibile identificare l'utente, la data e l'ora e il titolo.
  • Tutto è piegato in lettere minuscole e tutto ciò che non è alfanumerico viene rimosso e sostituito da trattini, il che rende il nome file facile da gestire usando strumenti semplici (ad es. Nessuno spazio che può confondere script scritti male, nessun due punti o altri caratteri proibiti su alcuni filesystem , e così via).

7
Per motivi di pulizia, ti consiglio di creare directory separate per ID utente in modo che se elimini un utente non dovrai cercare tutte le sue foto. - così98765/20130404125123-ad8a7dsf9-my-holiday-florida-23.jpg
Shadur,

1
Teoricamente l'unicità non è fornita dalla stringa casuale.
Kolyunya,

4
@Kolyuny, è vero, nel senso che l'unicità globale garantita non è una proprietà che anche i GUID hanno nella vita reale (anche le guide v1 sono state eliminate a causa dell'emissione di indirizzi MAC duplicati). Tutto quello che puoi ottenere è una probabilità statistica di unicità. Ma puoi assicurarti l'unicità controllando se il file esiste già (usando atomicamente CreateFilecon CREATE_NEW) e usando una casualità diversa se lo fa.
Ben

"Tutto è piegato in minuscolo e tutto ciò che non è alfanumerico viene rimosso e sostituito da trattini", lo
terrei

4

Non si desidera stressare le applicazioni (come Explorer) e bloccarlo quando si apre la directory. Anche se è improbabile che tu stia sottolineando il file system reale, devi tenerne conto se vuoi archiviare migliaia di file.

Se ti aspetti di archiviare migliaia di file, il mio suggerimento è di partizionare in cartelle. Ad esempio upload\silo001, upload\silo002ecc. È possibile bilanciare i file o attendere fino a quando una cartella raggiunge un determinato numero di file e quindi crearne un altro.

Per quanto riguarda la denominazione, chiamo sempre un file con un GUID perché è univoco a livello globale. Estraggo l'estensione dal caricamento e imposto l'estensione del file in modo che corrisponda, ma il nome effettivo viene impostato da un nuovo Guid.

Se stai facendo questo in combinazione con un RDBMS e hanno diverse categorie, vale a dire i prodotti, le categorie, ecc si potrebbe avere upload\products, upload\categoriese così via, e si potrebbe utilizzare l'ID riga come il nome del file.

In termini di buone pratiche, anch'io ho guardato in passato e non ho trovato nulla. Ho pensato a quanto sopra mentre discutevo con alcuni dei miei sviluppatori.


2

In una delle soluzioni su cui ho lavorato anni fa abbiamo fatto questo: sottocartelle per parte dell'ID utente, quindi se l'ID utente era 232950192

avremmo sottocartelle images / 23/29/50/192/232950192

nella cartella finale hanno cartelle per albuns e profili imgs ecc

Ma salviamo anche tutto nel database e lo conserviamo nel file system per un rapido accesso al web server (che ha anche la cache)

Ad ogni modo, l'immagine finale avrebbe il nome dell'immagine originale. Non abbiamo avuto bisogno di mantenere le versioni. Ma per quello che può contenere più sottocartelle sotto i nomi degli album finali o nella banca dati con un ID versione. bisogno di pensarci su come una volta che andrà in produzione sarebbe difficile cambiare le cose senza tempo e correzioni soggette a errori nella struttura attuale

È molto semplice creare una sottocartella in Java e creare un file al suo interno:

    File folder = new File(pathwithslashes);// like "images/23/29/50/192/232950192"
    folder.mkdirs();
    File imgFile = new File(folder, name);
    //Now get output stream etc

Per ottenere il timbro della data nelle sottocartelle: SimpleDateFormat sdf = new SimpleDateFormat ("/ yyyy / MM / dd /"); pathwithslashes = pathwithslashes + sdf.format (ora); // ora è una cartella File util.Date = new File (pathwithslashes);

Dot net /programming/5482230/c-sharp-equivalent-of-javas-mkdirs


+1 per suggerire directory nidificate. Penso che questo sia importante da considerare poiché diversi filesystem possono riscontrare problemi di prestazioni quando le cartelle contengono "troppi" file: stackoverflow.com/questions/197162/… , support.microsoft.com/kb/130694/en-us , ecc.
deizel

1
Sì, su un altro sistema si è verificato uno dei problemi del server Web quando abbiamo provato a rmdir su una dir che aveva più di 400.000 file. avevamo più cartelle come questa. quindi ho usato un programma personalizzato che ha chiamato dir / p per ottenere alcuni file da eliminare alla volta. ci sono volute alcune ore ma nessun tempo
morto

1

Consiglierei di usare solo md5 o qualcosa di concettualmente equivalente. Rinominando i file in base al loro contenuto, non solo si garantisce l'unicità (memorizzare sempre nella cache le immagini il più a lungo possibile, e con la ridenominazione basata sul contenuto, beh, con una corretta, è possibile memorizzare nella cache le immagini praticamente per sempre).

Inoltre, non è un grosso problema, ma non è un caso puramente ipotetico quando utenti diversi caricano esattamente la stessa immagine. Appena pronto avrai una piccola ottimizzazione della memorizzazione dei dati.

Per quanto riguarda qualsiasi altra cosa proposta: per quanto mi riguarda, sono fortemente contrario a conservare qualsiasi tipo di informazione ausiliaria nel nome di un file. Quando ero molto più giovane (e un po 'più magro :), sono stato uno sviluppatore Perl e ho avuto la dubbia abitudine di memorizzare quante più informazioni ausiliarie nel nome del file mi hanno permesso il senso comune, dal momento che le caratteristiche del modello di stringa del Perl sono fantastiche. E sono giunto alla conclusione che, parlando di sviluppo web, è sempre una scelta migliore mantenere i dati associati al file separatamente dal nome del file.

Tieni presente che al giorno d'oggi, quando dominano le interfacce mobili, il nome del file effettivo è una cosa meno importante rispetto a 5, 10 anni fa. Ma anche se questo sarà cruciale nel contesto della tua applicazione, puoi sempre coinvolgere un po 'di magia della vecchia scuola con il coinvolgimento Content-Disposition: attachment; filename="pretty_file_name.jpg"dell'intestazione HTTP, costruendo qualsiasi nome di file pertinente che desideri. Inoltre, i browser moderni stanno aprendo la strada al nuovo attributo HTML5, il download . Non credo che vedere il nome di un'immagine "leggibile dall'uomo" sia una cosa a cui dovresti pensare nella maggior parte dei casi.

UPD: è possibile effettuare una modifica per non avere troppi file in una directory - basta prendere le prime 3 lettere e creare dir.


1
Ma md5 è davvero unico?
I.devries

@ I.devries, non sono uno specialista, ma per quanto ne so, è abbastanza buono per questo scopo. Soprattutto se si controlla inoltre la dimensione del file, dal momento che l'algoritmo di hashing buono in realtà fa 'che le entità delle stesse dimensioni avrà meno probabilmente una collisione - stackoverflow.com/questions/2442632/...
shabunc

-1

Le possibilità di collisioni con qualcosa come sha4 sono infinitesime. Se combini l'hash con userid o anche una semplice data, ancor meno.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.