C# Path

Path type

A file is stored at a path. The .NET Framework provides effective ways to deal with filenames and paths. It introduces the Path type in the System.IO namespace. There are complexities when dealing with paths.

Example

You will often need to extract parts of filename paths. The .NET Framework team has considered this problem. The Path class is ideal. You can access it by adding "using System.IO" at the top of your file.

Framework: NET

Next:As an introduction, we see a short console program that shows four Path methods.

Console
Based on:

.NET 4.5

Program that uses Path methods: C#

using System;
using System.IO;

class Program
{
    static void Main()
    {
	string path = "C:\\stagelist.txt";

	string extension = Path.GetExtension(path);
	string filename = Path.GetFileName(path);
	string filenameNoExtension = Path.GetFileNameWithoutExtension(path);
	string root = Path.GetPathRoot(path);

	Console.WriteLine("{0}\n{1}\n{2}\n{3}",
	    extension,
	    filename,
	    filenameNoExtension,
	    root);
    }
}

Output

.txt
stagelist.txt
stagelist
C:\
Squares

We take the extension of the file, the actual filename, the filename without the extension, and the path root. The path root is "C:\\", with the trailing separator, even when the file is nested in many folders.

Also, you can get the filename alone by calling Path.GetFileName. This will return the filename at the end of the path, along with the extension. Some extensions are ".doc" and ".exe".

Also:There is a method to just get the extension, and one just to get the name with no extension—Path.GetFileNameWithoutExtension.

Example 2

Next we see the results of the Path methods on various inputs. Sometimes the methods handle invalid characters as you might expect. Sometimes they do not. This program calls three Path methods on an array of possible inputs.

Program that tests Path class: C#

using System;
using System.IO;

class Program
{
    static void Main()
    {
	string[] pages = new string[]
	{
	    "cat.aspx",
	    "really-long-page.aspx",
	    "test.aspx",
	    "invalid-page",
	    "something-else.aspx",
	    "Content/Rat.aspx",
	    "http://dotnetperls.com/Cat/Mouse.aspx",
	    "C:\\Windows\\File.txt",
	    "C:\\Word-2007.docx"
	};
	foreach (string page in pages)
	{
	    string name = Path.GetFileName(page);
	    string nameKey = Path.GetFileNameWithoutExtension(page);
	    string directory = Path.GetDirectoryName(page);
	    //
	    // Display the Path strings we extracted.
	    //
	    Console.WriteLine("{0}, {1}, {2}, {3}",
		page, name, nameKey, directory);
	}
    }
}

Output: reformatted

Input:                       cat.aspx
GetFileName:                 cat.aspx
GetFileNameWithoutExtension: cat
GetDirectoryName:            -

Input:                       really-long-page.aspx
GetFileName:                 really-long-page.aspx
GetFileNameWithoutExtension: really-long-page
GetDirectoryName:            -

Input:                       test.aspx
GetFileName:                 test.aspx
GetFileNameWithoutExtension: test
GetDirectoryName:            -

Input:                       invalid-page
GetFileName:                 invalid-page
GetFileNameWithoutExtension: invalid-page
GetDirectoryName:            -

Input:                       Content/Rat.aspx
GetFileName:                 Rat.aspx
GetFileNameWithoutExtension: Rat
GetDirectoryName:            Content

Input:                       http://dotnetperls.com/Cat/Mouse.aspx
GetFileName:                 Mouse.aspx
GetFileNameWithoutExtension: Mouse
GetDirectoryName:            http:\dotnetperls.com\Cat

Input:                       C:\Windows\File.txt
GetFileName:                 File.txt
GetFileNameWithoutExtension: File
GetDirectoryName:            C:\Windows

Input:                       C:\Word-2007.docx
GetFileName:                 Word-2007.docx
GetFileNameWithoutExtension: Word-2007
GetDirectoryName:            C:\
String type

Extensions. GetFileName­WithoutExtension will return the entire file name if there's no extension on the file.Path.GetDirectoryName returns the entire string except the file name and the slash before it.

Path methods and URLs. Please look at the table above where the directory name of the URL is received. The slashes are reversed into Windows-style slashes. This is not desirable with virtual paths or URLs.

Tip:The volume such as "C:\" is part of the directory name. The directory name doesn't include the trailing slash "\".

Syntax

Programming tip

When specifying paths in C# programs, we must use two backslashes "\\" unless we use the verbatim string syntax. A verbatim string uses the prefix character "@". Only one backslash is needed in this literal syntax.

String Literal
Program that uses verbatim string: C#

using System;
using System.IO;

class Program
{
    static void Main()
    {
	// ... Verbatim string syntax.
	string value = @"C:\directory\word.txt";
	Console.WriteLine(Path.GetFileName(value));
    }
}

Output

word.txt

Extensions

Letters of the alphabet: ABC

The Path type includes also support for extensions. We can get an extension with GetExtension. We can change an extension with ChangeExtension. The method names are obvious and easy-to-remember.

Note:GetExtension handles extensions of four letters. It also handles the case where a file name has more than one period in it.

Here:This next program briefly tests GetExtension.
You can find further details and benchmarks.

Path.GetExtensionPath.ChangeExtension
Program that uses GetExtension: C#

using System;
using System.IO;

class Program
{
    static void Main()
    {
	// ... Path values.
	string value1 = @"C:\perls\word.txt";
	string value2 = @"C:\file.excel.dots.xlsx";

	// ... Get extensions.
	string ext1 = Path.GetExtension(value1);
	string ext2 = Path.GetExtension(value2);
	Console.WriteLine(ext1);
	Console.WriteLine(ext2);
    }
}

Output

.txt
.xlsx

Combine

Method call

Path.Combine is a useful method, but there are edge cases it cannot solve. It can't figure out what you want if what it receives is confusing. But different inputs can yield the same result path.

Next:Here's a screenshot where we combine the folder "Content\\" with the file name "file.txt".

Path methods in Visual Studio debugger

The screenshot shows what values Path.Combine produced. It shows that the following two lines of code produce the same result. Path.Combine handles certain cases where you have directory separators in different positions.

Program that uses Path.Combine: C#

using System;

class Program
{
    static void Main()
    {
	//
	// Combine two path parts.
	//
	string path1 = System.IO.Path.Combine("Content", "file.txt");
	Console.WriteLine(path1);

	//
	// Same as above but with a trailing separator.
	//
	string path2 = System.IO.Path.Combine("Content\\", "file.txt");
	Console.WriteLine(path2);
    }
}

Output

Content\file.txt
Content\file.txt
Concept

The example above also shows how to refer to the Path class by specifying "System.IO.Path" instead of including the namespace at the top of your file. This may be useful in source files that are not file-IO oriented.

Tip:When using a C-style language such as C# or C++, you have to add the char "\" to your C# code, you must use \\ (two backslashes).

Note:That's because C# uses the backslash to escape characters, so you must escape it.

ASP.NET

ASP header

URLs and virtual paths are used in ASP.NET websites. The Path class does not work well for these paths, but it is still useful in websites. For each ASP.NET request, there is a Request.PhysicalPath.

And:The Request.PhysicalPath value is a Windows-style path. It works well with the Path class.

Code that tests extensions: C#

//
// This could be in your Global.asax file or in an ASPX page.
// It gets the physical path.
//
string physical = Request.PhysicalPath;
//
// Here we see if we are handling an ASPX file.
//
if (Path.GetExtension(physical) == ".aspx")
{
    //
    // Get the file name without an extension.
    //
    string key = Path.GetFileNameWithoutExtension(physical);
}

Random names

Question

Random file names are useful for many programs.
If you need to write a temp file
and the path is not important,
use Path.GetRandomFileName. You can also use this for random strings. But that isn't its primary purpose.

Path.GetRandomFileName

Tip:Here's the random string it yielded just now: zd4xcjmo.u4p. No file of that name likely exists.

Separators

Char type

The Path type also includes two properties for separators. These are good for creating code that is easy to understand. It is easier for some developers to read Path.DirectorySeparatorChar.

Next:I looked at these two properties in the debugger. The results of the properties are shown below.

Path.DirectorySeparatorChar result

"\\"

Path.AltDirectorySeparatorChar result

"/"

Temporary

There exist methods for getting temporary file names. When looking at them in the debugger, they point to a "Temp" folder in your User folder. Here are what Visual Studio's debugger says my temp file names equal.

Note:GetTempPath() has a separator character on the end, unlike Path.GetDirectoryName's return value.

Path.GetTempPath
Path.GetTempFileName result

C:\\Users\\allensamuel\\AppData\\Local\\Temp\\tmpC1D0.tmp
The output file name ends with ".tmp".

Path.GetTempPath result

C:\\Users\\allensamuel\\AppData\\Local\\Temp\\
The output path ends with the backslash character, \\.

Invalid chars

Exclamation mark

When accepting user input, your program should expect that invalid characters will be entered. For example, your program has a custom file name dialog. You need to quickly detect invalid path characters.

So:You can use the Path.GetInvalidFileNameChars and Path.GetInvalidPathChars methods.

Tip:You can use the character arrays returned by Path.GetInvalidFileNameChars and Path.GetInvalidPathChars with a Dictionary.

ToDictionary
Program that gets invalid characters: C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

class Program
{
    static void Main()
    {
	// First, we build a Dictionary of invalid characters.
	var dict = GetInvalidFileNameChars();
	// Next, we test the dictionary to see if the asterisk (star) is valid.
	if (dict.ContainsKey('*'))
	{
	    // This will run, because the star is in the Dictionary.
	    Console.WriteLine("* is an invalid char");
	}
    }

    /// <summary>
    /// Get a Dictionary of the invalid file name characters.
    /// </summary>
    static Dictionary<char, bool> GetInvalidFileNameChars()
    {
	// This method uses lambda expressions with ToDictionary.
	return Path.GetInvalidFileNameChars().ToDictionary(c => c, c => true);
    }
}

Output

* is an invalid char

Discussion

File

Path is a powerful class. It can change a file name's extension. It can determine whether the path is "rooted." This tells whether it is relative or absolute. You can also get information about the volume (usually a hard drive).

Tip:Getting the directory name of your string path is often useful. There are also benchmarks of Path.GetDirectoryName.

Path.GetDirectoryName

We should remember that Path is best used only for certain types of paths. Web addresses are considered paths, but in the .NET Framework they are URIs. And the Uri type is best for them.

Warning:I suggest that you don't use Path for URLs or virtual paths in ASP.NET. The Path type has inconsistencies with directory names.

Also:It doesn't have lookup tables for invalid characters, so you need to use the array or a Dictionary, such as the one we saw here.

File lists

List type

It is a common requirement to need to get lists of files in certain directories. Also, we show how to get recursive lists of files, by traversing subdirectories. These are not Path methods but they do return path strings.

Directory.GetFilesRecursive File List

Misc.

Some custom methods may be helpful when working with the Path class. For example, storing a list of reserved filenames and then testing to see if a filename is reserved can improve certain programs.

Path ExistsReserved Filenames

Optimization:There are ways to optimize the Path methods so that they are more efficient.

But:You must be careful not to change the functionality in ways that are detrimental.

GetFileNameWithout Extension

Uri

Uri type

The Uri type provides support for website addresses and paths. It contains many helper methods you can use to specify addresses of websites. If a path starts with "http", it is a better idea to use Uri.

UriUriBuilder

Summary

C# programming language

The Path class provides Windows-native path manipulations and tests. It is ideal for file names, directory names, relative paths, file name extensions and invalid character testing.

Thus:These examples hopefully put you on the path to good file path handling in the .NET Framework.


C#: File