Search code examples
c#fileinfo

FileInfo.MoveTo if file exists - rename


I have an application that moves files from one directory to another, but sometimes a conflict occurs and the file already exists in the destination directory.

When that happens, I want to move the file with a different name - e.g. if the file is named test.txt, I want to name it test.txt.1. That's okay, but how do I do it next time, if the file is again test.txt, but in the destination folder we have both test.txt and test.txt.1.

My problem is that I can't find the last created file so that I can read its index and increment it with 1. Any suggestions?

string sourcePath = "C:\\Files\\test.txt";
string filename = Path.GetFileName(sourcePath);
string pathTo = "C:\\Files\\test\\" + filename;

try
{
    var fileInfo = new FileInfo(sourcePath);
    fileInfo.MoveTo(pathTo);
}
catch (IOException ex)
{
    var fileInfo = new FileInfo(sourcePath);
    var file = Directory.GetFiles(pathTo, filename+".1").FirstOrDefault();
    if (file == null)
    {
        fileInfo.MoveTo(pathTo+".1");
    }
    else
    {
        //find the old file, read it's last index and increment it with 1
    }

}

Solution

  • I have rewritten your code a little because you were programming against the exception, which is something I really do not encourage.

    First, it checks if the original file already exists.

    Then, as your original code, it tries to create the file with a .1 indexer. If that is already present, it goes through the directory to locate all files that have the same filename.

    Last, it goes to find the last index used and increments it by one.

    Note that you could also skip the first if-statement in the else-statement because it will still search for the last index used; and if none is present, the lastIndex will stay 0 (with one increment so it will use 1 as index for the new file).

    var fileInfo = new FileInfo(sourcePath);
    
    // Check if the file already exists.
    if (!fileInfo.Exists)
        fileInfo.MoveTo(pathTo);
    else
    {
        var file = Directory.GetFiles(pathTo, filename + ".1").FirstOrDefault();
        if (file == null)
        {
            fileInfo.MoveTo(pathTo + ".1");
        }
        else
        {
            // Get all files with the same name.
            string[] getSourceFileNames = Directory.GetFiles(Path.GetDirectoryName(pathTo)).Where(s => s.Contains(filename)).ToArray();
    
            // Retrieve the last index.
            int lastIndex = 0;
            foreach (string s in getSourceFileNames)
            {
                int currentIndex = 0;
                int.TryParse(s.Split('.').LastOrDefault(), out currentIndex);
                if (currentIndex > lastIndex)
                    lastIndex = currentIndex;
            }
    
            // Do something with the last index.
            lastIndex++;
            fileInfo.MoveTo(pathTo + lastIndex);
        }
    }