Suponha que eu tenha um formulário no meu aplicativo Web em que os usuários possam fazer upload de uma foto do perfil.
Tenho poucos requisitos sobre tamanho de arquivo, dimensões, etc., mas quando o usuário carrega a imagem, como devo nomeá-los no meu sistema? Suponho que precisaria ser consistente e também único.
Talvez um GUID?
a5c627bedc3c44b7ae7c06a44fb3fcf8.jpg
Um timestamp?
129899740140465735.jpg
Um hash? Ex: md5
b1a9acaf295cf14ffbc5b6538294562c.jpg
Existe uma maneira padrão ou recomendada de fazer isso?
asp.net-mvc
file-handling
naming-standards
Rowan Freeman
fonte
fonte
Respostas:
Você deve tentar atingir dois objetivos: Exclusividade e utilidade.
O uso de um GUID garante exclusividade, mas um dia os arquivos podem ser desanexados da fonte original e você terá problemas.
Minha solução típica é incorporar informações cruciais no nome do arquivo, como o ID do usuário (se pertencer a um usuário) ou a data e hora do upload (se isso for significativo) ou o nome do arquivo usado ao enviá-lo.
Isso pode realmente salvar a sua pele um dia, quando as informações incorporadas no nome do arquivo permitem, por exemplo, recuperar-se de um bug ou excluir acidentalmente os registros. Se tudo o que você tem são GUIDs e você perde o catálogo, você terá um trabalho bem feito para limpá-lo.
Por exemplo, se um arquivo "My Holiday: Florida 23.jpg" for carregado, pelo ID do usuário 98765, em 04/04/2013 às 12:51:23, eu o chamaria assim, adicionando uma sequência aleatória
ad8a7dsf9
:20130404125123-ad8a7dsf9-98765-my-holiday-florida-23.jpg
fonte
98765/20130404125123-ad8a7dsf9-my-holiday-florida-23.jpg
CreateFile
comCREATE_NEW
) e usando aleatoriedade diferente, se existir.Você não quer estressar os aplicativos (como o Explorer) e causar falhas quando abrir o diretório. Embora seja improvável que você estresse o sistema de arquivos real, é necessário levar isso em consideração se estiver armazenando milhares de arquivos.
Se você espera armazenar milhares de arquivos, minha sugestão é particionar em pastas. Por exemplo
upload\silo001
,upload\silo002
etc. Você pode equilibrar seus arquivos ou aguardar até que uma pasta atinja um determinado número de arquivos e depois criar outro.No que diz respeito à nomeação, eu sempre nomeio um arquivo com um GUID porque é globalmente exclusivo. Pego a extensão do upload e defino a extensão do arquivo para corresponder, mas o nome real é definido em um novo Guid.
Se você estiver fazendo isso em conjunto com um RDBMS e tiver várias categorias, por exemplo, produtos, categorias, etc., poderá ter
upload\products
,upload\categories
etc., e poderá usar o ID da linha como o nome do arquivo.Em termos de melhores práticas, eu também procurei no passado e não encontrei nada. Eu vim com o acima exposto enquanto discutia com alguns dos meus desenvolvedores.
fonte
Em uma das soluções em que trabalhei anos atrás, fizemos o seguinte: subpastas para parte do ID do usuário, portanto, se o seu ID de usuário era 232950192
teríamos subpastas images / 23/29/50/192/232950192
na pasta final tem pastas para álbuns e imagens de perfil etc.
Mas também salvamos tudo no banco de dados e o mantemos no sistema de arquivos para acesso rápido ao servidor da Web (que também possui armazenamento em cache)
De qualquer forma, a imagem final teria o nome da imagem original. Não precisamos manter as versões. Mas para o que pode manter mais subpastas sob os nomes finais do álbum ou na base de dados com um ID de versão. é preciso pensar nisso uma vez que, uma vez que seja direcionado à produção, seria difícil mudar as coisas sem consumir tempo e correções propensas a erros na estrutura atual
É muito fácil criar uma subpasta em java e criar um arquivo nela:
Para obter o carimbo de data nas subpastas: SimpleDateFormat sdf = new SimpleDateFormat ("/ aaaa / MM / dd /"); pathwithslashes = pathwithslashes + sdf.format (now); // now is a util.Date Pasta do arquivo = new File (pathwithslashes);
Dot net /programming/5482230/c-sharp-equivalent-of-javas-mkdirs
fonte
Eu recomendaria usar apenas MD5 ou qualquer coisa conceitualmente equivalente. Ao renomear arquivos pelo resumo do conteúdo, você não apenas concede exclusividade (sempre armazene em cache as imagens pelo maior tempo possível e com a renomeação baseada em conteúdo, bem, com uma adequada, é possível armazenar em cache as imagens praticamente para sempre).
Além disso, não é grande coisa, mas, no entanto, não é um caso hipotético puro quando usuários diferentes carregam exatamente a mesma imagem. Apenas pronto para o uso, você terá uma pequena otimização do armazenamento de dados.
Quanto a qualquer outra coisa proposta: quanto a mim, sou um forte oponente em manter qualquer tipo de informação auxiliar em um nome de arquivo. Quando eu era muito mais jovem (e um pouco mais magro :), eu era um desenvolvedor de Perl e tinha o hábito duvidoso de armazenar tantas informações auxiliares no nome de arquivo quanto o senso comum me permitia, já que os recursos de padrão de string do Perl são impressionantes. E cheguei à conclusão de que, falando em desenvolvimento web, é sempre melhor escolher manter os dados associados ao arquivo separadamente do nome do arquivo.
Lembre-se de que hoje em dia, quando as interfaces móveis estão dominando, o nome real do arquivo é menos importante do que há 5, 10 anos atrás. Mas mesmo que isso seja crucial no contexto de sua aplicação, você sempre pode envolver alguma mágica da velha escola com o envolvimento do
Content-Disposition: attachment; filename="pretty_file_name.jpg"
cabeçalho HTTP, construindo qualquer nome de arquivo relevante que desejar. Além disso, os navegadores modernos estão abrindo caminho para o novo atributo HTML5, o download . Não acredito que realmente ver o nome da imagem "legível por humanos" seja algo que você deva pensar na maioria dos casos.UPD: Uma modificação pode ser feita para não haver muitos arquivos em um diretório - basta pegar as 3 primeiras letras e criar o diretório.
fonte
As chances de colisões com algo como sha4 são infinitesimais. Se você combinar o hash com o ID do usuário ou mesmo uma data simples, menos ainda.
fonte