2009-08-21 17 views
0

ファイルを別のフォルダに生成した後、名前の衝突に問題はありません。.Net:あるディレクトリから別のディレクトリにファイルを移動し、名前の衝突を避けるために

たとえば、私はCSVファイル名foo_20090820.csvを生成し、08/20/2009の後半にプログラムを再度実行すると、ファイルはfoo_20090820.csvになります。ターゲットフォルダには既にファイルが生成されています2番目のファイル。プログラムはエラーになります。

同じファイル名のターゲットフォルダを調べて、2番目のファイルの前に乱数を追加しようとしましたが、うまく機能しませんでした。

答えて

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というファイル上の関数があり、それが古いものを削除できる場合、最新のバージョンを使用したい場合です。 –

+0

例では、ループカウンタをインクリメントしていません。 –

+0

おっと...私は擬似機能コードを述べておくべきです。私はそれを修正します。ありがとう。 – EBGreen

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

0

私は先の解決策を少し進化させた自由を取った。ほとんどのIOExceptionは、呼び出し元によって処理される必要があります。

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; 
} 
関連する問題