ASP.NET中的文件上载 - 如何防止异常?

时间:2009-11-25 18:41:54

标签: asp.net file-io file-upload

我的网络表单中有一个FileUploader控件。如果正在上传的文件已存在,我想删除它,并用新上传的文件覆盖它。但是我得到一个错误,因为该文件正由另一个进程使用,因此应用程序无法删除它。示例代码:

if (FUpload.HasFile)
{
    string FileName = Path.GetFileName(FUpload.PostedFile.FileName);
    string Extension = Path.GetExtension(FUpload.PostedFile.FileName);
    string FolderPath = ConfigurationManager.AppSettings["FolderPath"];
    string FilePath = Server.MapPath(FolderPath + FileName);
    if (File.Exists(FilePath))
    {
        File.Delete(FilePath);
    }
    FUpload.SaveAs(FilePath);
}

除了在try / catch块中编写代码外,我还能做些什么吗?

3 个答案:

答案 0 :(得分:1)

生成唯一的临时文件名。完成后将其重命名为目的地。如果有人同时上传“相同”文件名,您可能仍会发生冲突。你应该总是在某处捕获文件系统错误。如果你不在这里,我可以建议global.asax中的全局错误处理程序。

答案 1 :(得分:0)

您可以使用其他名称保存文件,如果存在,请使用 File.Replace 替换旧文件

答案 2 :(得分:0)

在一天结束时,由于您网站上的潜在竞争条件(由于希望是并发用户),您无法绕过try / catch。 (你为什么厌恶它?)

UtkarshNo Refunds No Returns有正确的答案 - 用临时文件名保存,然后根据需要替换/覆盖现有文件名。一个好的方法是使用GUID作为临时文件名,以确保文件名不会发生冲突。

根据应用程序的性质,您可能会收集相当多的文件,由不同的用户上传,并存在许多潜在的名称冲突。根据应用程序的性质和规模以及安全边界,您可以考虑根据用户ID(如何在数据库中识别用户)为每个用户提供他/她自己的目录。每个用户都在那里上传他/她的文件。如果存在名称冲突,您可以退回给用户(如果需要,在会话中保留GUID名称)并询问他/她是否想要覆盖,并确信答案是安全的。

  • 如果用户拒绝覆盖,您可以删除临时文件。
  • 如果用户同意覆盖,您可以删除原件并编写新原件。
  • 在任何一种情况下,所有这些都本地化到用户自己的目录,因此(除非多个用户使用相同的ID登录),行为是安全的。

一般来说,这比任意覆盖文件名冲突更安全,更安全。

同样,由于竞争条件和您无法控制的其他情况,您需要在尝试写入文件系统时使用try / catch阻止为什么?如果驱动器空间不足怎么办?如果您尝试覆盖的文件被另一个进程合法使用,该怎么办?如果您尝试覆盖的文件具有NTFS权限,禁止Web进程触摸它,该怎么办?等等等等。你需要准备好处理这些例外。