2013年5月8日水曜日

ファイルが既に存在する場合に、ナンバリングして存在しないファイル名を取得する処理をLINQで。

タイトルにある、ちょっと無理めなお題を考えてみた。

すなわち、Windowsでよくある処理で、たとえば「U:\Test\Test.txt」が存在しない場合はそのままで、存在する場合は「U:\Test\Test (2).txt」を、それも存在する場合は(3)、(4)、…という風にナンバリングし、存在しないファイル名を返す、そんなメソッドを考えてみる。

LINQは意識せず、深く考えずに書いてみたらこうなった。

static string GetNumberedUniqueFilename(string filename)
{
  if (!File.Exists(filename))
    return filename;

  string d = Path.GetDirectoryName(filename),
    fn = Path.GetFileNameWithoutExtension(filename),
    ext = Path.GetExtension(filename);

  for (int i = 2; ; ++i)
  {
    var f = Path.Combine(d, string.Format("{0} ({1}){2}", fn, i, ext));
    if (!File.Exists(f))
      return f;
  }
}


これをLINQ使って書きなおしてみると…。難しいな…。こうか?

static string GetNumberedUniqueFilename(string filename)
{
  if (!File.Exists(filename))
    return filename;

  string d = Path.GetDirectoryName(filename),
    fn = Path.GetFileNameWithoutExtension(filename),
    ext = Path.GetExtension(filename);

  return Enumerable.Range(2, int.MaxValue - 2)
    .Select(i => Path.Combine(d, string.Format("{0} ({1}){2}", fn, i, ext)))
    .SkipWhile(f => File.Exists(f))
    .First();
}


…これはびみょーだなぁ…。

0 件のコメント:

コメントを投稿