Reputation: 9886
I have a method that copies selected image from an OpenFileDialog
to a defined location, and I want to check if an image with the same name exists, and if so to change the name on the fly.
Here is my method:
public void SaveImage(IList<AppConfig> AppConfigs, string ImageNameFilter)
{
string imgPath = AppConfigs[0].ConfigValue.ToString();
Int32 i = 0;
StringBuilder sb = new StringBuilder(selectedFileName);
while (File.Exists(imgPath + "\\" + ImageNameFilter + selectedFileName))
{
sb.Insert(i, 0);
i++;
//ImageNameFilter += (i++).ToString();
}
File.Copy(selectedFile, imgPath + "\\" + ImageNameFilter + selectedFileName);
}
ImageNameFilter
is a custom filter that is added at the beginning of each image and the users need this prefix to be able to recognize what the image is used for, only by seeing the prefix. selectedFileName
is the name of the image taken with SafeFileName
, which means it looks like this - imageName.jpeg
.
There are several problems that I have with this code. Firstly, I wanted to change the name like this - imageName1.jpeg, imageName2.jpeg, imageName3.jpeg...imageName14.jpeg..
, but if I'm using selectedFileName
with the +=
everything is added, even after the .jpeg
, which is not what I want. The only solution that I can think of is to use regex
, but I really want to find another way.
Also, incrementing i++
and adding it with +=
leads to unwanted result which is :
imageName1.jpeg, imageName12.jpeg, imageName123.jpeg...imageName1234567.jpeg
.
So, how can I get the result I want and the compromise I see here is to add underscore _
right after the ImageNameFilter
and then add i
at the beginning of selectedFileName
rather in the end as it is by default. But adding something to the beginning of the string is also something I don't know how to do. As you may see I tried StringBuiledr
+ Insert
, but I don't get the expected result.
Upvotes: 0
Views: 197
Reputation: 437784
Basically you need to separate the base file name from the extension (use the helpful methods on Path
to do this) before starting the loop, and then keep producing filenames. Each candidate will not be produced based on the last one (it's just based on fixed information and the current iteration count), so you don't need to involve a StringBuilder
at all.
Here's one neat way to do it in two steps. First, set up the bookkeeping:
var canonicalFileName = ImageNameFilter + selectedFileName;
var baseFileName = Path.GetFileNameWithoutExtension(canonicalFileName);
var extension = Path.GetExtension(canonicalFileName);
Then do the loop -- here I 'm using LINQ instead of a loop statement because I can, but there's no essential difference from a stock while
loop:
var targetFileName = Enumerable.Range(1, int.MaxValue - 1)
.Select(i => Path.Combine(imgPath, baseFileName + i + extension))
.First(file => !File.Exists(file));
File.Copy(selectedFile, targetFileName);
Upvotes: 3
Reputation: 21275
Use Path.GetFileNameWithoutExtension
or String.TrimEnd('.')
to get the FileName without extension. You can use FileInfo
to get the extension as well.
Upvotes: 1