2009-08-21 129 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; 
} 
相關問題