Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

After spending the last 4 years writing in VB.Net I have decided to bite the bullet and all code written at home will be written in C#. Given time I think I might try to move into a C# position if things go smoothly.

 

Anyway in the past I did some training in Java so the syntax is reasonably familiar and VB and C# are closer than ever now.

 

So the first question is quite simple. It is regarding the use of @ in C#. If I put the line:

folderToDelete = folderToDelete.Substring(0, folderToDelete.LastIndexOf("\"));

It would fail, this is to do with the backspace. It is simple to fix it:

folderToDelete = folderToDelete.Substring(0, folderToDelete.LastIndexOf(@"\"));

What I am not sure of is what the @ is actually doing here, can someone explain.

 

The next question regards some other code I wrote using a fileSystemWatcher that is used to delete files/folders etc. The first thing is the codes does everything it is supposed to do, so I am happy with it in that respect. I just wondered if it could be cleaner than the way I am doing it.

 

The problem I came across was breaking out of the recursive function. I VB I would have probably used exit sub etc. In C# I used return; instead but if you look at the code you will see I had to do quite a lot to unwind the recursion. Anyway have a laugh! :o

private void fswSource_Deleted(object sender, System.IO.FileSystemEventArgs e)
{
   if (Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["AllowDelete"]))
   {
       if (e.Name.Contains(@"."))
       {
           //This is a file we are deleting.  
           if (File.Exists(_DestinationFolder + e.Name))
           {
               try
               {
                   File.Delete(_DestinationFolder + e.Name);
               }
               catch (Exception)
               {
                   //Consume exception
               }
           }  
       }
       else
       {
           //This is a folder we are deleting a folder.
           if (Directory.Exists(_DestinationFolder + e.Name))
           {
               try
               {
                   //Make reference of rootfolder, to compare to later.                                                      
                   _RootFolder = _DestinationFolder + e.Name;                                                        
                              
                   //Call sub to delete folders/files etc.
                   Delete(_DestinationFolder + e.Name);                          

                   //Reset flag.
                   _stopDeleting = false;
               }
               catch (Exception)
               {
                   //Consume exception.
               }
           }
       }                            
   }
}

/// Deletes file/s / folder/s using recursion.
/// </summary>
private void Delete(string folderToDelete)
{
   while (folderToDelete != _RootFolder && _stopDeleting == false)
   {       
       //The code in this loop applies to all child folders of the folder we are deleting.

       //Attempt to delete any empty folders.
       foreach (string d in Directory.GetDirectories(folderToDelete))
       {
           try
           {
               Directory.Delete(d);
           }
           catch (Exception)
           {                       
               //Consume exception.
           }
       }

       //Attempt to delete the current folder in the case of it being empty.
       try
       {
           Directory.Delete(folderToDelete);

           //Move up to parent folder when no more files are left to delete.
           folderToDelete = folderToDelete.Substring(0, folderToDelete.LastIndexOf(@"\"));
           if (_stopDeleting == false)
           {
               Delete(folderToDelete);
               if (_stopDeleting == true)
               {
                   return;
               }
           }
           else
           {
               return;
           }
       }
       catch (Exception)
       {                  
           //Consume exception.
       }
       
       //Recursively move through child folders.
       foreach (string d in Directory.GetDirectories(folderToDelete))
       {
           if (_stopDeleting == false)
           {
               Delete(d);
               if (_stopDeleting == true)
               {
                   return;
               }
           }
           else
           {
               return;
           }
       }

       //Delete any files in folder.
       foreach (string f in Directory.GetFiles(folderToDelete))
       {
           try
           {
               File.Delete(f);
           }
            catch (Exception)
            {                     
                //Consume exception.
            }                    
       }

       try
       {
           //Move up to parent folder when no more files are left to delete.
           folderToDelete = folderToDelete.Substring(0, folderToDelete.LastIndexOf(@"\"));
           if (_stopDeleting == false)
           {
               Delete(folderToDelete);
               if (_stopDeleting == true)
               {
                   return;
               }
           }
           else
           {
               return;
           }
       }
       catch (Exception)
       {                   
           //Consume exception.
       } 
   }
   //This code applies to the parent folder.

   //Attempt to go into any child folders.
   foreach (string d in Directory.GetDirectories(folderToDelete))
   {
       try
       {
           Delete(d);
       }
       catch (Exception)
       {
           //Consume exception.
       }
   }

   //Delete any files in folder.
   foreach (string f in Directory.GetFiles(folderToDelete))
   {
       try
       {
           File.Delete(f);
       }
       catch (Exception)
       {
           //Consume exception.
       }
   }

   //Attempt to delete the current folder in the case of it being empty.
   try
   {
       Directory.Delete(folderToDelete);             
   }
   catch (Exception)
   {
       //Consume exception.
   }

   _stopDeleting = true;
   return;
}

 

I am preparing myself for some criticism but if it improves me I can take it.

 

Cheers, Dave. :D :D :D

  • Administrators
Posted

First question is easiest so ...

 

In C# (and other 'C' like languages) strings can contain escape sequences, the '\' character is used to denote these. i.e. a new line is '\n' a tab is '\t' and so on. If you really want to use a '\' you have to double it up and use '\\' - not a problem but it can make cutting and pasting strings from other places a pain.

 

Prefixing the string with a '@' symbol simply stops the esacping of the string and doesn't apply any special meaning to the '\' character.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Posted

Recursive Delete

 

Are you just trying to recursively delete a directory?

 

private void Delete(string folderToDelete)
{
   //Delete files
   foreach (string file in Directory.GetFiles(folderToDelete)) {
       File.Delete(file);
   }

   //Recursively delete subdirectories
   foreach (string dir in Directory.GetDirectories(folderToDelete)) {
       Delete(dir);
   }

   //Delete current directory
   Directory.Delete(folderToDelete);
}

 

I don't understand why your code needs to traverse up the directory tree, since it is always invoked from the root folder.

 

Good luck :cool:

Never trouble another for what you can do for yourself.
Posted

Code style tips

 

Some more comments:

 

It is poor practice to catch Exception and then do nothing with it. If you want to ignore exceptions caused by file or directory access, then you could catch IOException or one of its subclasses (such as DirectoryNotFoundException or FileNotFoundException), and other more meaningful exceptions such as UnauthorizedAccessException. If you're still writing and debugging your application, you should want to know about pretty much every other exception so you can correct your code. When your application is out in the field, any exceptions thrown within the application should be logged or traced at the very least.

 

Secondly, your fswSource_Deleted method relies on the presence of "." to distinguish between files and directories. Filenames without "." are perfectly valid, as are directory names with ".". I suggest using only Directory.Exists and File.Exists to determine how to delete - the "." check is redundant.

 

Finally, return at the end of a void method is unnecessary, but does no harm.

 

Good luck :cool:

Never trouble another for what you can do for yourself.
Posted

Thanks for the replies, there is so much information there, I can say that even though I have been playing around with this for a few days or so I have learned so much.

 

The code I posted has a lot of improving to do and I said that at the time. But I am refactoring and adding a lot of stuff to it. It it going from a little couple of days project to something far more complete.

 

As I mentioned this project is my first really in C# so I want to get it working and put everything into it I can.

 

On a funny note I have to tell about the FileSystemWatcher. I was watching the events as they fired whilst I pasted some folders/files into the folder the FileSystemWatcher was watching. I noticed that besides the create event firing, which I was expecting. The changing event also fired. I could see no reason why this would happen. But after giving it some thought it occured to me that if for example I recursively paste files and folders into any sub folders this would fire the changing events. What I have done is add the event handlers programatically and when I start one of the events I programatically remove the other events handlers temporarily until the process is complete and then if the finally clause of my try block add the events back. Seems to work really fast and clean.

 

Anyway I take the point about bad exception handling and can I assure you that when this code is finished I will remove as much esxception handling as is safe to do so. Any catch blocks let will at least log the exceptions and catch more specific exceptions.

 

Many thanks to you for your help!!!!!

Posted (edited)

I don't think that Paul was suggesting that you remove your try/catch blocks; I think he meant you should do something with the exception.

 

As a rule of thumb, I put the code for every method in a try/catch block.

 

On private methods I throw; on public methods I log the exception and then throw; it. I never use throw ex;

 

There is a difference between these two examples

 

...
Catch(Exception ex)
{
   throw ex;
}
// the exception is re-thrown from THIS POINT and the stack trace is reset

 

vs.

 

...
Catch(Exception ex)
{
   throw;
}
// the exception is re-thrown as if it hadn't been caught, stack trace is preserved

 

See this article for more information.

 

My 2¢

Edited by Nate Bross

~Nate�

___________________________________________

Please use the [vb]/[cs] tags on posted code.

Please post solutions you find somewhere else.

Follow me on Twitter here.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...