Use Path.Combine to avoid ugly program failures!

I’ve so often seen people combining paths like this:

string path = basePath + "\\" + filename;

Sometimes they use Path.DirectorySeparatorChar or even check wether basePath or filename already contains. The program then fails with exceptions like "could not find file c:\Program Files\MyProggie\\settings.xml" or even worse files like MyProggiesettings.xml are created, just because the person configuring the program isn’t aware of how and where to use "\".

This what System.IO.Path.Combine(string, string) does for you:

  • It validates both paths. They can be null or empty, but if they contain invalid path chars, an argument exception is thrown.
  • It uses Path.DirectorySeparatorChar to combine, but will never end up having two separators or none.
  • It takes only the second path if it is absolute, so you never get paths like "c:\data\d:\data\logs\myfile.xml"
  • If one of the paths is null or empty, the other one is returned.

Simple combinations

If the second path is relative, it will get combined with the first path.

  • Path.Combine("abc", "file.xml") => "abc\file.xml"
  • Path.Combine("abc\", "file.xml") => "abc\file.xml"
  • Path.Combine("c:\abc\", "file.xml") => "c:\abc\file.xml"
  • Path.Combine("c:\abc\", "data\file.xml") => "c:\abc\data\file.xml"
  • Path.Combine("", "data\file.xml") => "data\file.xml"
  • Path.Combine("c:\abc", "") => "c:\abc"

Absolute second path

If the second path is absolute, the first one will be ignored. (See also Path.IsPathRooted(string))

  • Path.Combine("c:\abc", "\file.xml") => "\file.xml"

    (if the second path starts with the DirectorySeparatorChar it is also treated as absolute!)
  • Path.Combine("c:\abc", "c:\file.xml") => "c:\file.xml"

Example Usage

For NT Services the root directory often is "c:\Windows\System32", so if you want to store something relatively, you should combine it with AppDomain.CurrentDomain.BaseDirectory.

So if you want to write something to a configured file within your application you could code it like this:

var file = ConfigurationManager.AppSettings["MyXmlFile"];
if (string.IsNullOrEmpty(file))
    throw new ConfigurationErrorsException(
                      "Missing app setting: 'MyXmlFile'.");

var filePath = Path.Combine(
                    AppDomain.CurrentDomain.BaseDirectory, 
                    file);

using (var writer = new StreamWriter(filePath))
{
    // write something to your file ...
}

kick it on DotNetKicks.com

Advertisements

4 thoughts on “Use Path.Combine to avoid ugly program failures!

  1. You say “It uses Path.DirectorySeparatorChar to combine, but will never end up having two separators or none.” This doesn’t seem to be how Path.Combine works at all in practice:

    “C:” and “Temp” returns “C:Temp” which is not valid.

    “C:\” and “Temp” returns “C:\Temp” which is fine.

    “C:\\” and “Temp” returns “C:\\Temp” and so on, so it seems like a lot more validation is needed.

    • Well, you’re right. When you pass already invalid path information, it won’t help you alot. What I meant was to avoid “C:\” and “\Temp” (separately configured somewhere) to end up in “C:\\Temp”.

      Thanks for the information, though!

  2. Grr.

    Usually, I want Path.Combine(“C:\\temp\\”, “\\file.xml”)=> “C:\\temp\\file.xml”.

    I can definitely understand why Combine’s been implemented the way it is, but it does mean I can’t escape including my own combine routine (yet again) 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s