背景:如果文件已经存在,我尝试将文件移动到另一个位置并想重命名它们。有多个进程可以同时移动具有相同名称的文件。
通常我会使用这种方法:
string oldPath = @"smth1";
string newPath = @"smth";
if (File.Exists(newPath))
{
filename = GetNewFilename(newPath);
}
//Problem, if file gets created here!!!*
File.Move(oldPath, newPath);
如果我尝试移动文件,并且另一个进程在(*)时刻创建了一个具有相同名称的文件,则会收到IOException。 这里的问题是我没有可以捕获的特定“ FileAlreadyExistsException”。
我在这里错过了什么吗,还是有其他方法可以解决此问题?
答案 0 :(得分:1)
那么,如果您想确定的话,就可以处理所有可能引发的错误。
try
{
File.Move(oldPath, newPath);
}
catch (ArgumentNullException)
{
//source of dest filename is null
}
catch(ArgumentException)
{
//source or dest file name/path not valid
}
catch(UnauthorizedAccessException)
{
//no permission
}
catch (DirectoryNotFoundException)
{
//dir not found
}
catch(PathTooLongException)
{
//path too long
}
catch(NotSupportedException)
{
//source or desk name is invalid format
}
catch (IOException)
{
if (File.Exists(newPath))
//file exists
else if (!File.Exists(oldPath))
//old path does not exist
else
//Unknown error
}
您可以在MSDN
上找到所有可能的选项。答案 1 :(得分:0)
尝试在开始时创建文件。如果那不起作用,那么您就知道它已经存在。如果它可以正常工作,那么您不希望移动现有文件,而希望将旧文件复制到新文件中,然后删除旧文件。这样一来,您就不必再丢失创建的新文件了。
答案 2 :(得分:0)
您可以在类中创建一个静态字段,并使用lock
语句来确保只有一个线程可以创建或重命名文件,因此其他线程不能创建具有相同名称的文件。
lock(_lockObject)
{
//rename or create your file here
}
答案 3 :(得分:0)
使用File.Move
时,如果文件已经存在或找不到原始文件,则会抛出IOException
;就是这样。
如果遇到此异常,则需要适当的算法,例如在文件名或类似名称后附加一个计数器,以重新尝试执行该算法。我会增加一个最大尝试次数的度量,以便万一由于任何原因而无法成功时,它就会爆发。
但是,在此递归尝试移动文件的过程中,建议您在每次尝试时都检查源文件是否存在以及目标文件是否不存在。如果您确实确实得到了IOException
,我也只会重新尝试;除所有其他例外情况外,还应做其他工作。