文件上传:要保存到的文件名称是什么?

问题描述 投票:1回答:5

我将文件上传控件添加到我的ASP.NET 2.0网页,以便用户可以上传文件。文件将以用户的名字存储在服​​务器的文件夹中。我想知道在保存到服务器时命名文件的最佳选择是什么。需要考虑安全性,性能,处理文件的灵活性等。

我正在考虑的选项:

  1. 使用与输入文件名相同的名称进行上传
  2. 从输入文件名开始添加用户ID +随机数+文件名
  3. 创建随机数+当前时间(以秒为单位,并使用该数字保存文件)。将有一张表格将该号码映射到用户上传的位置

还有其他吗?最好的方法是什么?

asp.net file-upload
5个回答
5
投票

从不使用用户输入的文件名。不要使用用户名。而是使用用户ID(我假设您的用户具有唯一的ID)。

请勿使用原始文件名。使用解决方案编号3,加上用户ID代替用户名。

作为参考,PHP几年前就存在一个漏洞:一个人可以伪造一个HTTP POST请求,该请求带有文件上传,文件名如“ ../../anything.php”和php _FILES数组,应该包含经过清理的值,但未检测到此类文件名,因此可以在文件系统中的任何位置写入文件。


2
投票

我会使用]的组合>

  • 用户ID
  • 随机生成的字符串(例如GUID)
  • 示例PDF文件名:23212-dd503cf8-a548-4584-a0a3-39dc8be618df.pdf

这样,用户可以根据需要上传任意数量的文件,而不会出现文件名冲突,并且您也可以仅通过查看文件名就指出哪些文件属于哪些用户。

我不认为需要在文件名中包含任何其他信息,因为可以从文件的属性中检索上载时间/日期等。

此外,您应该将文件存储在安全的位置

,外部用户(例如您的网站的访问者)无法访问。而是通过代理网页将文件传递给他们(从安全位置读取文件,并将数据传递给用户)。对于此解决方案,需要一个数据库来跟踪文件,其位置等。

这还使您能够通过您的代码控制哪些用户有权访问哪些文件。


更新:

这是有关如何实现代理网页解决方案的描述。
  1. 创建名称为GetFile.aspx的Web表单
  2. GetFile.aspx采用一个名为fileid的查询参数,该参数用于标识要获取的文件。例如:
    http://www.mypage.com/GetFile.aspx?fileid=100
  3. 使用fileid参数在数据库中查找文件位置,以便可以将其读取并发送给用户。在Web窗体中,使用Request.QueryString("fileid")获取文件ID,并将其用于如下所示的查询中(SQL):
    从用户文件的文件位置WHERE FileID = 100
  4. ]] >>
  5. 使用System.IO.FileStream读取文件并通过Response.Write输出其内容。请记住,首先要使用content type设置适当的Response.ContentType,以便客户端浏览器正确处理请求的文件(请参阅this post上的asp.forums.net和帖子中也提到的MDSN article,这两者都讨论了一种自动确定适当的内容类型的方法)。
  6. 如果选择这种方法,以后可以轻松实现自己的简单安全性或自定义操作,例如确保用户在发送文件之前登录到您的网站,或者用户只能访问自己上传的文件,或记录哪些用户下载了哪些文件等。可能性无限;-)

看看System.IO.Path class,因为它具有许多可以使用的有用功能,例如:

检查文件名中哪些字符无效:

System.IO.Path.GetInvalidPathChars();

获取随机文件名:

System.IO.Path.GetRandomFileName();

在临时目录中获得唯一的随机文件名

System.IO.Path.GetTempFileName();

我会选择选项3。与用户映射这些文件的表将始终提供其他用途。如果使用映射,则在尝试调试问题时,将用户名或ID附加到文件的唯一好处是。

我可能会使用GUID而不是随机数,但两者都可以。我认为重要的事情是

  1. 没有用户名作为文件名的一部分,而不是存储文件的任何部分
  2. 请勿将原始文件名用作存储文件的任何部分
  3. 使用随机数或GUID确保没有重复的文件
  4. 向文件添加用户ID将有助于解决手动调试问题

除了眼神之外,还有更多……我想你已经知道了!

您正在谈论哪种文件?如果它们的大小甚至太大或太小,以致文件组可能很大,我会立即建议您为方法增加一些灵活性。

  1. 创建一个表,该表存储到各种文件存储的根路径(这可能是驱动器,unc路径,以及环境所支持的内容)。最初它将有一个条目,它将是您的第一个存储位置。要保留此数据的一个不错的属性是可以在此处存储多少空间。
  2. 维护文件相关数据表(id {guid},创建日期,路径数据的外键,文件大小)
  3. 将文件写入尚有空间的根目录(查询存储在根目录中的所有文件大小并与该根目录容量进行比较)
  4. 使用GUID作为名称来写文件(混淆文件系统上的文件)。如果安全要求(敏感文件),则可以不使用文件扩展名来写。
  5. 根据从根/年{number} /月{number} /天{number} /file.extension开始的创建日期写入文件>
  6. 有了这种性质的系统-即使您不需要/不需要它,您现在也可以更轻松地重定位文件。您可以更好地管理文件。您可以更好地管理文件集合。等等,我以前使用过这个系统,发现它非常灵活。一旦文件存储变得很大,需要处理一些事情,处理存储到文件系统但由数据库管理的文件可能会有点失控。另外,至少在Windows情况下……将大量文件存储在一个目录中通常不是一个好主意(按创建日期分解内容的原因)。

    仅当您的体积大且占地面积大时才真正需要这种复杂性。


1
投票

看看System.IO.Path class,因为它具有许多可以使用的有用功能,例如:


0
投票

我会选择选项3。与用户映射这些文件的表将始终提供其他用途。如果使用映射,则在尝试调试问题时,将用户名或ID附加到文件的唯一好处是。


0
投票

除了眼神之外,还有更多……我想你已经知道了!

© www.soinside.com 2019 - 2024. All rights reserved.