2009-08-21 125 views
0

如何在生成文件后将文件移动到另一个文件夹而没有名称冲突问题?.Net:将文件从一个目录移动到另一个目录并避免名称冲突

例如,我生成一个CSV文件名foo_20090820.csv,如果我再次在08/20/2009运行程序,那么该文件将是foo_20090820.csv,因为在我的目标文件夹中已经有一个文件生成第二个文件。该程序会遇到错误。

我试图找到相同的文件名的目标文件夹,并在第二个文件前添加一些随机数,但它不能很好地工作。

有什么想法吗?

回答

4

下面是我如何处理这个伪代码:

newName = "foo_20090820.csv" 
i = 1 
while file exists newName 
    newName = "foo_20090820-" + i.ToString() + ".csv 
    i++ 
While Loop 
Move oldFile to newName 
+0

这是处理它的最好方法。唯一的另一种方式是,如果你只是想使用最新版本,那么文件中存在一个名为Exist的函数,它会告诉你文件是否存在,如果存在,你可以删除旧文件。 – 2009-08-21 20:27:59

+0

在你的例子中,你没有递增循环计数器。 – 2009-08-21 22:17:05

+0

糟糕...我应该说伪代码。我会修好它。谢谢。 – EBGreen 2009-08-21 23:46:29

1

另一个想法是编码在文件名中的时间。我已经看到你有编码的日期;我所建议的是时间。

所以你最终的东西是这样的:

foo_yyyyMMdd_HHmmss(加的.csv当然)

这将增加小时(24小时时钟格式),分钟和秒,你的名字。

请注意,您不仅可以按照移动的顺序对这些文件进行排序,但其文件名会告诉您何时移动了

2

如果您完全不希望发生碰撞,您可以使用GUID。

0

这是对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到文件名的解决方案。

+0

虽然它仍然可以正常工作,但这段代码会生成文件名,如foo1.csv,foo12.csv,foo123.csv。正如我所说,这将是功能性的,但如果能够查看文件并根据写入顺序快速做出决定非常重要,则应该将原始基本名称粘贴到var并附加到该文件。 – EBGreen 2009-08-24 15:05:12

0

我冒昧地进一步发展先前的解决方案。大多数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; 
} 
相关问题