我的网络表单中有一个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
块中编写代码外,我还能做些什么吗?
答案 0 :(得分:1)
生成唯一的临时文件名。完成后将其重命名为目的地。如果有人同时上传“相同”文件名,您可能仍会发生冲突。你应该总是在某处捕获文件系统错误。如果你不在这里,我可以建议global.asax中的全局错误处理程序。
答案 1 :(得分:0)
您可以使用其他名称保存文件,如果存在,请使用 File.Replace 替换旧文件
答案 2 :(得分:0)
在一天结束时,由于您网站上的潜在竞争条件(由于希望是并发用户),您无法绕过try
/ catch
。 (你为什么厌恶它?)
Utkarsh和No Refunds No Returns有正确的答案 - 用临时文件名保存,然后根据需要替换/覆盖现有文件名。一个好的方法是使用GUID作为临时文件名,以确保文件名不会发生冲突。
根据应用程序的性质,您可能会收集相当多的文件,由不同的用户上传,并存在许多潜在的名称冲突。根据应用程序的性质和规模以及安全边界,您可以考虑根据用户ID(如何在数据库中识别用户)为每个用户提供他/她自己的目录。每个用户都在那里上传他/她的文件。如果存在名称冲突,您可以退回给用户(如果需要,在会话中保留GUID名称)并询问他/她是否想要覆盖,并确信答案是安全的。
一般来说,这比任意覆盖文件名冲突更安全,更安全。
同样,由于竞争条件和您无法控制的其他情况,您需要在尝试写入文件系统时使用try
/ catch
阻止。为什么?如果驱动器空间不足怎么办?如果您尝试覆盖的文件被另一个进程合法使用,该怎么办?如果您尝试覆盖的文件具有NTFS权限,禁止Web进程触摸它,该怎么办?等等等等。你需要准备好处理这些例外。