views:

108

answers:

4

I am new to C# and am trying to write a program that navigates the local file system using a config file containing relevant filepaths. My question is this: What are the best practices to use when performing file I/O (this will be from the desktop app to a server and back) and file system navigation in C#?

I know how to google, and I have found several solutions, but I would like to know which of the various functions is most robust and flexible. As well, if anyone has any tips regarding exception handling for C# file I/O that would also be very helpful.

Thanks!!!

badPanda

+5  A: 

You don't need a separate library, use the classes in the System.IO namespace like File, FileInfo, Directory, DirectoryInfo. A simple example:

var d = new DirectoryInfo(@"c:\");
foreach(FileInfo fi in d.GetFiles())
    Console.WriteLine(fi.Name);
RedFilter
Sorry, again, new to C#. I meant that I have found multiple techniques, but it does appear that the methods for them are all contained in System.IO.File class.
badpanda
@badpanda: Which class/method you select depends on the specifics of what you are trying to do. Can you provide more details?
RedFilter
Sure. I need to read in files to be sent to a web service later. These will most likely be infopath files.
badpanda
I'll also need some information from the file properties, if that is relevant.
badpanda
See http://www.csharp-examples.net/file-attributes/ for an example of accessing attributes.
RedFilter
+2  A: 

What various libraries are you talking about?

I would pretty much stick to System.IO.Directory and such. It has everything you need.

Something like:

foreach (var file in System.IO.Directory.GetFiles(@"C:\Yourpath"))
{
    // Do ya thang.
}
John Gietzen
+2  A: 

There are various classes you can use in the System.IO namespace, including File, FileInfo, Directory, and DirectoryInfo.

As for practices... as with any IO, make sure you close any streams you open. You also may need to utilize a Disposable object, so look into the using keyword.

Chris Dwyer
+1  A: 

System.IO is all you need :)

As regards exception handling. Unless we are expecting an exception, we should never catch it. Truly unexpected exceptions should go unhandled. [looks guilty] ok, the only exception is at the highest level, and only for reporting purposes, such as

// assuming console program, but every application Console, WinForm,
// Wpf, WindowsService, WebService, WcfService has a similar entry point
class Program
{
    // assume log4net logging here, but could as easily be
    // Console.WriteLine, or hand rolled logger
    private static readonly ILog _log = LogManager.GetLogger (typeof (Program));

    static void Main (string[] args)
    {
        AppDomain.CurrentDomain.UnhandledException += 
            CurrentDomain_UnhandledException;
    }

    private static void CurrentDomain_UnhandledException (
        object sender, 
        UnhandledExceptionEventArgs e)
    {
        _log.
            Fatal (
            string.Format (
            "Unhandled exception caught by " +
            "'CurrentDomain_UnhandledException'. Terminating program.", 
            e.ExceptionObject);
    }

}

If you are expecting an exception then one of the following is acceptable

// example of first option. this applies ONLY when there is a
// well-defined negative path or recovery scenario
public void SomeFunction ()
{
    try
    {
        string allText = System.IO.File.ReadAllText ();
    }

    // catch ONLY those exceptions you expect
    catch (System.ArgumentException e)
    {
        // ALWAYS log an error, expected or otherwise.
        _log.Warn ("Argument exception in SomeFunction", e);

        // if the use-case\control flow is recoverable, invoke
        // recovery logic, preferably out of try-catch scope
    }
}

or

// example of second option. this applies ONLY when there is no
// well defined negative path and we require additional information
// on failure
public void SomeFunction ()
{
    try
    {
        string allText = System.IO.File.ReadAllText ();
    }

    // catch ONLY those exceptions you expect
    catch (System.ArgumentException innerException)
    {
         // do whatever you need to do to identify this
         // problem area and provide additional context
         // like parameters or what have you. ALWAYS
         // provide inner exception
         throw new SomeCustomException (
             "some new message with extra info.",
             maybeSomeAdditionalContext,
             innerException);

         // no requirement to log, assume caller will
         // handle appropriately
    }
}
johnny g