如何在生成文件后将文件移动到另一个文件夹而没有名称冲突问题?.Net:将文件从一个目录移动到另一个目录并避免名称冲突
例如,我生成一个CSV文件名foo_20090820.csv,如果我再次在08/20/2009运行程序,那么该文件将是foo_20090820.csv,因为在我的目标文件夹中已经有一个文件生成第二个文件。该程序会遇到错误。
我试图找到相同的文件名的目标文件夹,并在第二个文件前添加一些随机数,但它不能很好地工作。
有什么想法吗?
如何在生成文件后将文件移动到另一个文件夹而没有名称冲突问题?.Net:将文件从一个目录移动到另一个目录并避免名称冲突
例如,我生成一个CSV文件名foo_20090820.csv,如果我再次在08/20/2009运行程序,那么该文件将是foo_20090820.csv,因为在我的目标文件夹中已经有一个文件生成第二个文件。该程序会遇到错误。
我试图找到相同的文件名的目标文件夹,并在第二个文件前添加一些随机数,但它不能很好地工作。
有什么想法吗?
下面是我如何处理这个伪代码:
newName = "foo_20090820.csv"
i = 1
while file exists newName
newName = "foo_20090820-" + i.ToString() + ".csv
i++
While Loop
Move oldFile to newName
另一个想法是编码在文件名中的时间。我已经看到你有编码的日期;我所建议的是时间。
所以你最终的东西是这样的:
foo_yyyyMMdd_HHmmss(加的.csv当然)
这将增加小时(24小时时钟格式),分钟和秒,你的名字。
请注意,您不仅可以按照移动的顺序对这些文件进行排序,但其文件名会告诉您何时移动了。
如果您完全不希望发生碰撞,您可以使用GUID。
这是对EBGreen的解决方案的改进,它可以避免检查存在和创建文件之间的竞争状况。
bool SafeMove(string sourceFilename, string destFilename)
{
for (int i = 0; i < RetryThreshold; ++i)
{
try
{
File.Move(sourceFilename, destFilename);
return true;
}
catch(IOException)
{
destFilename =
Path.GetFilenameWithoutExtension(destFilename) + i.ToString() +
Path.GetExtension(destFilename);
}
}
return false;
}
有一些问题与此代码,但它表明了试图重试Move()
操作失败之后。您绝对应该执行一些更智能的异常处理,因为并非所有的IOExceptions
都意味着重试的原因。此外,返回false
并不明智,因为我们失去了错误上下文。
或者,如果你不目录或文件名的可读性而言,使用JP的追加Guid
到文件名的解决方案。
虽然它仍然可以正常工作,但这段代码会生成文件名,如foo1.csv,foo12.csv,foo123.csv。正如我所说,这将是功能性的,但如果能够查看文件并根据写入顺序快速做出决定非常重要,则应该将原始基本名称粘贴到var并附加到该文件。 – EBGreen 2009-08-24 15:05:12
我冒昧地进一步发展先前的解决方案。大多数IOExceptions需要由调用者处理。
private static string moveFileWithoutCollisions(string newDirectory, string filePath)
{
string fileName = Path.GetFileName(filePath);
string newFilePath = Path.Combine(newDirectory, fileName);
string bareFileName = Path.GetFileNameWithoutExtension(fileName);
string extension = Path.GetExtension(fileName);
while (true)
{
int suffix = 0;
while (File.Exists(newFilePath))
{
suffix++;
string fileNameWithSuffix = bareFileName + suffix + extension;
newFilePath = Path.Combine(newDirectory, fileNameWithSuffix);
}
try
{
File.Move(filePath, newFilePath);
}
catch (IOException)
{
if (File.Exists(newFilePath))
{
// Race condition: someone put a file there with the same name. Find a new name.
continue;
}
else
{
throw;
}
}
break;
}
return newFilePath;
}
这是处理它的最好方法。唯一的另一种方式是,如果你只是想使用最新版本,那么文件中存在一个名为Exist的函数,它会告诉你文件是否存在,如果存在,你可以删除旧文件。 – 2009-08-21 20:27:59
在你的例子中,你没有递增循环计数器。 – 2009-08-21 22:17:05
糟糕...我应该说伪代码。我会修好它。谢谢。 – EBGreen 2009-08-21 23:46:29