Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Finding a free file name and number combination

4.80/5 (4 votes)
30 Jun 2013CPOL 12.8K  
One of the tasks we often have to do is rename a file before creating a new version. But when we want to keep multiple versions, how do we find out which ones already exist?

Introduction

One of the tasks we often have to do is rename a file before creating a new version. The obvious way to do this is to rename the existing file so it has a number suffix:

MyFile.log
MyFile1.log
MyFile2.log
...

But when we want to keep multiple versions, how do we find out which ones already exist? 

Background

This started with a QA question and I thought it worth converting my answer to a method and submitting it for posterity! :laugh:

The Copy'n'Paste bit 

C#
/// <summary>
/// Find the number at the end of the string
/// </summary>
private Regex fileNumber = new Regex("\\d+$", RegexOptions.Compiled);
/// <summary>
/// Get the next free file number given a base file name
/// </summary>
/// <param name="path">Path to base file</param>
/// <returns>Path to free file name</returns>
private string GetFreeFileNumber(string path)
    {
    string pathOnly = path.Substring(0, path.LastIndexOf('\\') + 1);
    string nameOnly = Path.GetFileNameWithoutExtension(path);
    string extOnly = Path.GetExtension(path);
    string[] files = Directory.GetFiles(pathOnly, nameOnly + "*" + extOnly);
    int largest = files.Max(f => GetFileNumber(f));
    return string.Format("{0}{1}{2}{3}", pathOnly, nameOnly, largest + 1, extOnly);
    }
/// <summary>
/// Get the number (if any) at the end of a filename
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
private int GetFileNumber(string file)
    {
    Match m = fileNumber.Match(Path.GetFileNameWithoutExtension(file));
    if (!m.Success) return 0;
    return int.Parse(m.Value);
    }

How it works  

First, break the base file path into its important parts: The folder it is in, the file name, and the extension.

Then read all the files in that folder with the same extension, that start with the file name.

Then use a Regex to extract the number from each filename, and use Linq extension methods to find the largest. We can then return a filename which includes a number one larger. 

File.Move[^] can then rename the existing file.  

Using the code  

Easy: Call the GetFreeFileNumber method, passing the existing base file path:

C#
MessageBox.Show(GetFreeFileNumber(@"D:\Temp\MyLogFile.log"));

History

2013 Jun 30 Addition of "+ 1" to the pathOnly substring - otherwise it returns a filename with a "\" missing... :O

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)