0

I'm facing a challenge with an app doing some process then it moves a file to a new directory. It is working fine, but if a file with the same name is found, I get an unhandled exception.

I do not want to overwrite the file if it already exists, and I don't want to give users a message. If the file already exists i want to move the file to NewDirectory and rename the file with a different name.

The solutions I try never catch the unhandled exception.

string NewDirectory = (@"D:\Files\edited\");
Directory.CreateDirectory(NewDirectory);
string seconds = DateTime.Now.ToString("-ss");
string NewName = "Example Txt" + "-2.2-";
string FullPath = (NewDirectory + NewName + ".txt");

if (File.Exists(FullPath))
{
    File.Move(file, NewDirectory + NewName + seconds + ".txt");
    Console.WriteLine(NewName + seconds);
}
else
    File.Move(file, NewDirectory + NewName + ".txt");

Console.WriteLine(NewName);

screenshot for exception

mason
  • 31,774
  • 10
  • 77
  • 121
i.fathy
  • 33
  • 1
  • 8
  • What action do you want to take if the file already exists? Overwrite it? – mason Apr 25 '17 at 13:40
  • no, i already explained that in my question, i want to append the new file name to avoid the exception. – i.fathy Apr 25 '17 at 13:41
  • what do you know about error handling? –  Apr 25 '17 at 13:41
  • Do you know about `try/catch`? – mason Apr 25 '17 at 13:42
  • Have a look at this. http://stackoverflow.com/a/42224803/1845593 Alternative: you might check if file exist, if yes delete and then move – user1845593 Apr 25 '17 at 13:43
  • 2
    Seconds is probably a bad choice. There are only 60 of them, and they repeat once per minute.. I'd honestly use a simple int, and increment it in a while loop while file exists. Once file doesn't exist, add it to the filename and move it (don't forget ToString). – Aaron Apr 25 '17 at 13:45
  • @mason: my experience is still small, but im learning, i did try `try/catch` but may be my experience and findings didnt help me get the required info, can you let me know if you suggest a specific `try/catch` solution that help me? – i.fathy Apr 25 '17 at 14:09
  • Note that if the `source` and `destination` are the same you should do nothing, not rename the file. – Jodrell Apr 25 '17 at 14:09
  • @user1845593 : as stated, i want to keep both files, i dont want to delete the older one. – i.fathy Apr 25 '17 at 14:09
  • @i.fathy: so do what is in that link, but don't delete the file! or append a GUID or nanoseoncds or do the cound of files and increment... something like thatt – user1845593 Apr 25 '17 at 14:10
  • @i.fathy, you know that `File.Move` deletes the `source` file, right? – Jodrell Apr 25 '17 at 14:11
  • @Aaron : i understand your concern, however actually the situation of finding a file with the same name in this specific folder will be extremely rare when i release my app, so having a file with same names and also same 2 digits of SS, will be impossible, thats why i thought of SS, i didnt want more digits of the time because im already using the file creation date in name, so i dont want to add more date/time digits which will make the name very long and confusing. **i agree with you and my initial trial was while loop + increment but i failed, can you show me how to do it?** – i.fathy Apr 25 '17 at 14:12
  • @i.fathy it won't be rare. It will be almost always. Your computer can do *way* more than 1 operation per second. Just give it a try, it will work. – Aaron Apr 25 '17 at 14:17

3 Answers3

1

You can try to create the directory with a random name. For this, use Path.GetRandomFileName(). Then use a while for check if the file exist. Also i realize that you also move the file if it doesnt exist. Is that right? Maybe that is your problem

This is the code for generate the file name:

string NewName = Path.GetRandomFileName() + ".txt";
string FullName = Path.Combine(NewDirectory, NewName);

Is also better use Path.Combine() method for creating paths.

aperezfals
  • 1,341
  • 1
  • 10
  • 26
  • i dont want to get a random name, the whole app is created to read data inside a text file and name the file based on a specific string inside each file. can you advise why is it better to use 'string FullName = Path.Combine(NewDirectory, NewName);' than 'string FullName = (NewDirectory + NewName + ".txt");' ? – i.fathy Apr 25 '17 at 14:05
  • The method Path.Combines checks if the separator exist so it will not duplicate the separators and also if the path have invalid characters. It is just prettier. It's Not a REAL problem to cocatenate strings – aperezfals Apr 25 '17 at 14:11
0

You're probably trying to create Files that already exist because you are using seconds to append. Depending on how often you are calling this, it is likely that you may be trying to create two files with the same name. I would try using the full DateTime reference, or an arbitrary incrementing number to append.

Also, it's always advisable to use Path.Combine() when concatenating file paths: Example to try:

string NewDirectory = (@"D:\Files\edited\");
Directory.CreateDirectory(NewDirectory);
string seconds = DateTime.Now.ToString("-ss");
string NewName = "Example Txt" + "-2.2-.txt";
string FullPath = Path.Combine(NewDirectory, NewName);

if (File.Exists(FullPath))
{
  NewName = NewName + _SomeClassInteger + ".txt"
  File.Move(file, Path.Combine(NewDirectory, NewName));
  Console.WriteLine(NewName + seconds);
}
else
  File.Move(file, FullPath);

Console.WriteLine(NewName);
Martin Davies
  • 169
  • 13
  • 1
    the thing is, during my debugging and trials, yes the file name might exist, but using the "-ss" in it, it doesnt exist and that i checked visually, however is till get exception can you explain what is "_SomeClassInteger" and what is the benefit of "Path.Combine" ? – i.fathy Apr 25 '17 at 14:03
  • Path.Combine is just a 'safety' thing is you like - you will always get a valid path back (prevents missing '/', or doubling up etc.). In your example it probably doesn't make a difference, it's just good practice. _SomeClassInteger is just arbitrary (an int set up at class level for example) - just the point being the name should be appended with a unique number - something less likely than seconds (which only has 60 values) to cause a clash. I'm intrigued though - I'll have a look properly on my system later and see if I can replicate your issue how you describe it :-) – Martin Davies Apr 26 '17 at 10:22
0

Unfortunately I still get exception.

I have decided to add the "DateTime.Now.ToString("- ss")" to the name step to avoid getting the exception, or at least reduce the probability of getting file already exists

string NewDirectory = (@"D:\Files\edited\");
Directory.CreateDirectory(NewDirectory);
string seconds = DateTime.Now.ToString("- ss");
string NewName = "Example Txt" + "-2.2-" + seconds;
    File.Move(file, NewDirectory + NewName + ".txt");
    Console.WriteLine(NewName);
i.fathy
  • 33
  • 1
  • 8