views:

127

answers:

4

Is there a built in .NET function to get a unique filename if a filename already exists? So if I try and save MyDoc.doc and it already exists, the file will save with name MyDoc(1).doc, the same way a browser download works for example.

If not, what is the most efficient way to achieve this result?

I am using the File.Move function at the moment btw.

+3  A: 

check the name against Regex *.\(\d+\), if it doesn't match, add (1), if it matches increment the number in brackets.

Andrey
You could probably leverage the regexp so that the digits would form a match group, making it easier to isolate and replace them.
Steven Sudit
@Steven Sudit yes, yes. this was something like proof of concept.
Andrey
Doing anything by checking if it exists before creating it causes potential race conditions. The file should be locked if it was successfully found not to exist, as in my answer.
Codesleuth
@Andrey: And it's fine for that. I recently wrote some code that checked whether a directory name matched "New folder" in the general case, and the regexp for that was surprisingly complex. What you're suggesting involves rebuilding, not just detecting, so it's even more so. Having said that, I think this is the very best solution in terms of flexibility.
Steven Sudit
+1  A: 

I don't know, but it's not hard to build one yourself:

if filename does not exists then 
    save file as filename
else
n = 1
while filename(n) exists: 
    n += 1
save file as filename(n)
Lie Ryan
Yes I know it's not a complex programming problem, but I was interested in if there was a more elegant solution than a brute force loop.
fearofawhackplanet
+2  A: 
Codesleuth
This would work, but I'm not entirely happy with it. One undesirable characteristic is that it's going to throw as many exceptions as there are conflicts. I'd rather do File.Exists until I find an opening, then use File.Move. If the move fails, I'd increment my filename and retry. This handles the race condition as an exceptional case, rather than the typical one.
Steven Sudit
@Steven Sudit true that could also work, but `File.Move` will also throw exceptions (the same ones actually). Maybe it would be worth writing a version of this that does what you say.
Codesleuth
@Steven Sudit: changed the answer - you were completely right about the previous one. The new one looks to me like it makes more sense.
Codesleuth
I like your changes. I would still suggest a few things, if you don't mind: 1) I get the impression from the OP that the file has already been written to a temp name and just needs to be renamed to its final one. If so, then you would use Move instead of Copy. 2) File offers higher performance than FileInfo, although perhaps at a small cost to convenience. 3) From my own recent experience, I've found that regexp with matching groups, like Andrey suggested, are more flexible. You can start with a name like "file (3).txt" and still work.
Steven Sudit
+2  A: 

As the other answers shows, there are multiple ways of doing this, but one thing to be aware of is if other processes than your can create files you have to be careful, since if you check that a filename is available, by the time you save your new file, some other process might already have saved a file using that name and you'll overwrite that file.

ho1
Good point. Although unlikely in my circumstances.
fearofawhackplanet
This is a race condition and if your software has security implication then consider malicious attempts to trigger exceptions.
Pratik
I added an answer that solves this, but I clarify how it can be improved (although I say if I created it, it's mine ;] )
Codesleuth