假设我的Web应用程序中有一个表单,用户可以在其中上传个人资料图片。
我对文件大小,尺寸等几乎没有要求,但是当用户上传图像时,如何在系统上命名它们?我想它需要保持一致并且也是唯一的。
也许是GUID?
a5c627bedc3c44b7ae7c06a44fb3fcf8.jpg
时间戳记?
129899740140465735.jpg
哈希?例如:md5
b1a9acaf295cf14ffbc5b6538294562c.jpg
有没有标准或推荐的方法来做到这一点?
假设我的Web应用程序中有一个表单,用户可以在其中上传个人资料图片。
我对文件大小,尺寸等几乎没有要求,但是当用户上传图像时,如何在系统上命名它们?我想它需要保持一致并且也是唯一的。
也许是GUID?
a5c627bedc3c44b7ae7c06a44fb3fcf8.jpg
时间戳记?
129899740140465735.jpg
哈希?例如:md5
b1a9acaf295cf14ffbc5b6538294562c.jpg
有没有标准或推荐的方法来做到这一点?
Answers:
您应该尝试实现两个目标:唯一性和有用性。
使用GUID可以保证唯一性,但是有一天,文件可能会从其原始来源中分离出来,然后会遇到麻烦。
我的典型解决方案是将关键信息嵌入文件名中,例如userID(如果它属于用户)或上载的日期和时间(如果这很重要),或者上载时使用的文件名。
当文件名中嵌入的信息使您能够(例如)从错误中恢复或意外删除记录时,这可能真的可以节省一天的时间。如果您只有GUID,并且丢失了目录,则将很难完成此工作。
例如,如果用户ID 98765在2013/04/04的12:51:23上载了“我的假期:佛罗里达23.jpg”文件,则我将这样命名,并添加一个随机字符串ad8a7dsf9
:
20130404125123-ad8a7dsf9-98765-my-holiday-florida-23.jpg
98765/20130404125123-ad8a7dsf9-my-holiday-florida-23.jpg
CreateFile
和CREATE_NEW
),如果存在则使用不同的随机性。
您不希望对应用程序(例如Explorer)施加压力,并在打开目录时使其崩溃。虽然不太可能要强调实际的文件系统,但是如果要存储成千上万个文件,则需要考虑到这一点。
如果您希望存储数千个文件,我的建议是将其分区到文件夹中。例如upload\silo001
,upload\silo002
等。您可以平衡文件,也可以等到文件夹命中一定数量的文件然后再创建一个。
关于命名,我总是使用GUID命名文件,因为它是全局唯一的。我确实从上传中提取了扩展名,并将文件的扩展名设置为匹配,但是实际名称是从新的Guid设置的。
如果与RDBMS一起执行此操作,并且具有多个类别(即产品,类别等),则可以具有upload\products
,upload\categories
等等,并且可以将行ID用作文件名。
在最佳实践方面,我过去也没有发现任何东西。在与一些开发人员讨论时,我想到了以上内容。
在几年前我尝试的一种解决方案中,我们执行了以下操作:部分用户ID的子文件夹,因此,如果您的用户ID为232950192
我们将有子文件夹images / 23/29/50/192/232950192
在最终文件夹中,有用于相册和个人资料imgs的文件夹
但是我们也将所有内容保存在数据库中,并将其保留在文件系统中,以便快速访问Web服务器(也具有缓存)
无论如何,最终图像将具有原始图像名称。我们不需要保留版本。但是,在最终专辑名称下或在数据库中使用版本ID可以保留更多子文件夹的原因。需要思考一下,一旦投入生产,就很难在没有时间和不容易纠正当前结构的情况下更改事物
在java中创建子文件夹并在其中创建文件非常容易:
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
要在子文件夹中获取日期戳:SimpleDateFormat sdf = new SimpleDateFormat(“ / yyyy / MM / dd /”); pathwithslashes = pathwithslashes + sdf.format(now); //现在是一个util.Date File文件夹= new File(pathwithslashes);
我建议只使用md5或任何概念上等效的东西。通过按内容摘要重命名文件,您不仅在授予唯一性(总是尽可能长地缓存图像,而且基于内容的重命名,再加上适当的重命名,实际上可以永远缓存图像)。
同样,这没什么大不了的,但是当不同的用户上传完全相同的图像时,这并不是一个纯粹的假设情况。开箱即用,您将进行小的数据存储优化。
至于其他建议:至于我,我坚决反对在文件名中保留任何类型的辅助信息。当我还年轻(也更苗条:)时,我一直是Perl开发人员,并且习惯于以常识允许的方式在文件名中存储尽可能多的辅助信息,因为Perl字符串模式功能很棒。我得出的结论是,谈到Web开发,始终将与文件关联的数据与文件名分开保存始终是更好的选择。
请记住,如今,在移动接口占主导地位的情况下,实际文件名已比10年前的5变得不那么重要了。但是,即使这对于您的应用程序而言至关重要,但您始终可以通过使用Content-Disposition: attachment; filename="pretty_file_name.jpg"
HTTP标头来构造一些老式的魔术,从而构造所需的任何相关文件名。另外,现代浏览器正在为新的HTML5属性(下载)铺平道路。我不认为实际上看到“人类可读”的图像名称是大多数情况下您应该考虑的事情。
UPD:可以进行修改,以使一个目录中没有太多文件-只需输入前3个字母并创建dir。
与sha4之类的东西碰撞的机会是很小的。如果您将哈希与用户ID或什至是简单日期结合在一起,则更是如此。