In this article, we will learn how to efficiently rename single or multiple files in a folder using C#, making file management easier and more organized.

To download the source code for this article, you can visit our GitHub repository.

Let’s start.

Finding Files in a Folder

Before we get into the details of renaming files in C#, it’s important to know how to locate them. We’ll start by exploring the fundamental concept of finding files within a folder.

The Directory class from the System.IO namespace provides methods we can use for retrieving a list of all the files in a folder. 

Let’s use one of its methods to retrieve a list of files from a folder and its subfolders:

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!
public static IEnumerable<string> FindFilesInFolder(string directoryPath)
{
    return Directory.EnumerateFiles(directoryPath, "*", SearchOption.AllDirectories);
}

Our method takes a single directoryPath parameter and returns an IEnumerable<string>, which may be enumerated to retrieve a list of all the files in the specified directory and all subdirectories.

It uses the EnumerateFiles() method to get a list of all the files in the directory path.

The * wildcard character used to match any file name and the SearchOption.AllDirectories value used to specify whether or not to include subdirectories in the search are both optional arguments.

To test our method, let’s create a directory with files dynamically:

var directoryPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());

Directory.CreateDirectory(directoryPath);

for (var i = 1; i < 5; i++)
{
    var filePath = Path.Combine(directoryPath, $"File{i}.txt");
    File.Create(filePath).Dispose();
}

var filesInFolder = FindFilesInFolder(directoryPath);

foreach (var file in filesInFolder)
{
    var fileName = Path.GetFileName(file);
    Console.WriteLine(fileName);
}

Firstly, we create a random directory within the temporary directory. Next, we create four empty text files in the new directory: File1.txt, File2.txt, File3.txt, and File4.txt.

Then, we assign the list of files returned by the static FindFilesInFolder() method to the filesInFolder variable.

Lastly, our foreach loop iterates over the list of files and gets the file names with Path.GetFileName(), and displays them on the console:

File1.txt
File2.txt
File3.txt
File4.txt

Renaming a File in a Folder

Now that we know how to find files in a folder, let’s learn how to rename them.

To rename files, the System.IO namespace provides two classes File and FileInfo. We can use either one for creating, copying, deleting, moving, and renaming files.

We will learn how to use each class to rename a file, as well as compare the key differences between the methods.

Rename Files Using File Class

The File class is a static class that provides methods for common file operations, including renaming files.

Let’s rename a file using the File class:

public static void RenameFileWithFileClass(string oldFile, string newFile) 
{
    File.Move(oldFile, newFile);
}

Here, our method takes two parameters, oldFile representing the file we wish to rename and newFile indicating the desired new file name.

Then we invoke the File.Move() method to rename the file.

Now, let’s use our RenameFileWithFileClass() method:

var directoryPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
Directory.CreateDirectory(directoryPath);

var oldFile = Path.Combine(directoryPath, "File1.txt");
File.Create(oldFile).Dispose();

var newFile = Path.Combine(directoryPath, "File_v1.txt");

RenameFileWithFileClass(oldFile, newFile);

Console.WriteLine($"Renamed {Path.GetFileName(oldFile)} to {Path.GetFileName(newFile)}");

We create a temporary directory and store it in the directoryPath variable, and then create a file named File1.txt within it, and store it in the oldFile variable.

Next, we specify the new file name in the newFile variable and call our method to rename the file.

The ensuing console output succinctly confirms the successful file renaming operation:

Renamed File1.txt to File_v1.txt

Rename Files Using FileInfo Class

Unlike the File class, the FileInfo class is a non-static class that provides properties and methods for manipulating files. It also provides us with a method for renaming a file.

Let’s rename a file using the FileInfo class:

public static void RenameFileWithFileInfoClass(string oldFile, string newFile)
{
    var file = new FileInfo(oldFile);

    file.MoveTo(newFile);
}

In this example, our method takes the full path to the old file and the new file as parameters.

It creates a new FileInfo object for the old file and assigns it to the file variable, and then calls MoveTo() to move the old file to the new location (i.e. to rename the file).

Let’s see our RenameFileWithFileInfoClass() method in action:

var directoryPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
Directory.CreateDirectory(directoryPath);

var oldFile = Path.Combine(directoryPath, "File2.txt");
File.Create(oldFile).Dispose();

var newFile = Path.Combine(directoryPath, "File_v2.txt");

RenameFileWithFileInfoClass(oldFile, newFile);

Console.WriteLine($"Renamed {Path.GetFileName(oldFile)} to {Path.GetFileName(newFile)}");

Here, we also create a temporary directory and store it in the directoryPath variable, and then create a file named File2.txt within it, and store it in the oldFile variable.

Next, we specify the new file name in the newFile variable and call our method to rename the file.

The console message verifies the successful execution:

Renamed File2.txt to File_v2.txt

Which Method Should We Use?

While both methods achieve the same goal of changing a file name, they differ in their implementation and suitability for specific scenarios.

The File.Move() method is a concise and efficient option for renaming a single file, as it requires only the source file’s path and destination path, making it a straightforward choice for one-off renaming tasks.

In contrast, the FileInfo.MoveTo() method offers a more object-oriented approach. It utilizes FileInfo instance for the source file, allowing subsequent operations on the same file without redundant security checks, and potentially enhancing performance.

While both perform security checks, if we are reusing the same object, the FileInfo instance method is preferable. It avoids unnecessary security checks, offering a more object-oriented and efficient approach.

Ultimately, for a single file renaming task, the File.Move() method is a concise and efficient choice. Conversely, if multiple operations on the same file are anticipated and an object-oriented approach is preferred, the FileInfo.MoveTo() method may be more suitable.

Batch Rename Files

Batch renaming is a great way to change the names of multiple files at once. It can save us a lot of time, especially if we have many files to rename. It can also help us ensure that our file names are consistent and accurate.

Let’s batch-rename image files with date and time. First, let’s do it using the File class:

public static void RenameImagesWithDateTime(string directoryPath)
{
    var allowedExtensions = new[] { ".jpg", ".png", ".jpeg", ".gif" };

    var imageFiles 
        = Directory.EnumerateFiles(directoryPath)
        .Where(file =>
            allowedExtensions.Contains(Path.GetExtension(file),
                StringComparer.OrdinalIgnoreCase));

    foreach (var imageFile in imageFiles)
    {
        var creationTime = File.GetCreationTime(imageFile);

        var fileExtension = Path.GetExtension(imageFile);

        var newFileName = $"Image_{creationTime:yyyy-MM-dd_HHmmss}{fileExtension}";

        var newFilePath = Path.Combine(directoryPath, newFileName);

        File.Move(imageFile, newFilePath);
    }
}

This method takes a directory path to enumerate and filters the results to only include images with the following extensions: .jpg, .png, .jpeg, and .gif. The filtered files are then stored in the imageFiles variable.

Thereafter, we iterate over the filtered files, extracting their creation times and file extensions. Next, we create new file names, prefixed with Image_ and the file creation time in yyyy-MM-dd_HHmmss format.

Finally, we combine the directory path and the new file name to create a new file name and rename the files using the File.Move() method.

Let’s run the method to batch-rename our image files:

var directoryPath = Path.Combine(Path.GetTempPath(), "MyImages");

RenameImagesWithDateTime(directoryPath);

We provide the full directory path to the images we want to rename and pass it to the RenameImagesWithDateTime() method to rename our files.

Now, let’s update the method to use the FileInfo class. We just need to update the foreach loop code:

foreach (var imageFile in imageFiles)
{
    var file = new FileInfo(imageFile);

    var creationTime = file.CreationTime;

    var fileExtension = file.Extension;

    var newFileName = $"Image_{creationTime:yyyy-MM-dd_HHmmss}{fileExtension}";

    var newFilePath = Path.Combine(directoryPath, newFileName);

    file.MoveTo(newFilePath);
}

Using the FileInfo class, we create a new object for each file, retrieve the creation time and extension, and move the old files to the new path.

Error Handling and Validation

When working with files in C#, it is important to handle errors and validate inputs to ensure that our code is robust and reliable.

Some common errors that can occur when renaming files include IOException, SecurityException DirectoryNotFoundException, UnauthorizedAccessException, FileNotFoundException and PathTooLongException.

These errors can occur if the specified path is invalid, the caller does not have permission to rename the file, the specified path or file name exceeds the system-defined maximum length or the new file name is invalid.

Handling all possible exceptions, not just the common ones listed above, can be done using a simple try-catch block, which ensures reliable code.

Conclusion

This article has explored essential C# techniques for file manipulation, focusing on finding and renaming files within a folder. We have also discussed error handling to ensure robust and reliable code.

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!