-
-
Save milseman/d8bef5d49f1ae3db97b19f9ffd0f85a8 to your computer and use it in GitHub Desktop.
C# path examples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Linq; | |
using System.Diagnostics; | |
namespace HelloWorld { class Program { | |
// Info: {fullyQualified, root, fullPath} | |
// Traditional path test cases: | |
static string[] traditionalPaths = { | |
// {false, nil, <unchanged>} | |
@"", | |
// {false, nil, C:\Users\User\Documents\PathExplorer\C} | |
@"C", | |
// {false, C:, C:\Users\User\Documents\PathExplorer} | |
@"C:", | |
// {true, C:\, <unchanged>} | |
@"C:\", | |
// {false, nil, C:\Users\User\Documents\PathExplorer\ABC:\} | |
@"ABC:\", | |
// {false, nil, C:\Users\User\Documents\PathExplorer\:\} | |
@":\", | |
// {false, nil, <unchanged>} | |
@"1:\", | |
// {true, C:\, <unchanged>} | |
@"C:\foo\bar.exe", | |
// {false, C:, C:\Users\User\Documents\PathExplorer\foo\bar} | |
@"C:foo\bar", | |
// {false, \, C:\foo\bar.exe} | |
@"\foo\bar.exe", | |
// {false, nil, C:\Users\User\Documents\PathExplorer\foo\bar.exe} | |
@"foo\bar.exe", | |
// {false, \, C:\} | |
@"\", | |
// {false, \, C:\} | |
@"/", | |
// {true, c:\, c:\} | |
@"c:/", | |
// {true, c:\, c:\foo\bar\} | |
@"c:/foo/bar/", | |
}; | |
// UNC path test cases: | |
static string[] uncPaths = { | |
// {true, \\server\share, <unchanged>} | |
@"\\server\share\", | |
// {true, \\server\share, <unchanged>} | |
@"\\server\share", | |
// {true, \\server\share, <unchanged>} | |
@"\\server\share\folder\file.txt", | |
// {true, \\server\, <unchanged>} | |
@"\\server\", | |
// {true, \\server, <unchanged>} | |
@"\\server", | |
// {true, \\system07\C$, <unchanged>} | |
@"\\system07\C$\foo", | |
// {true, \\system07\ABC$, <unchanged>} | |
@"\\system07\ABC$\foo", | |
// {true, \\system07\ABC:, <unchanged>} | |
@"\\system07\ABC:\foo", | |
// {true, \\system07\ABC, <unchanged>} | |
@"\\system07\ABC\foo", | |
// {true, \\system07\C:, <unchanged>} | |
@"\\system07\C:\foo", | |
// {true, \\server1\util, <unchanged>} | |
@"\\server1\util\file\", | |
// {true, \\server1\e:, \\server1\e:\util\file\} | |
@"\\server1\e:\util\\file\", | |
// {true, \\.\UNC\server\share, <unchanged>} | |
@"\\.\UNC\server\share\foo", | |
// {true, \\.\UNC\Server\Share, <unchanged>} | |
@"\\.\UNC\Server\Share\Test\Foo.txt", | |
// {true, \\server, <unchanged>} | |
@"\\server", | |
// {true, \\server\, <unchanged>} | |
@"\\server\", | |
// {true, \\server\, \\server\} | |
@"\\server\\", | |
// {true, \\server\, \\server\folder} | |
@"\\server\\folder", | |
// {true, \\server\x, <unchanged>} | |
@"\\server\x\folder", | |
// {true, \\server\, \\server\folder\file.txt} | |
@"\\server\\folder\file.txt", | |
// {true, \\, <unchanged>} | |
@"\\", | |
// {true, \\x, <unchanged>} | |
@"\\x", | |
// {true, \\, <unchanged>} | |
@"\\\", | |
// {true, \\, \\\} | |
@"\\\\", | |
// {true, \\, \\} | |
@"//", | |
// {true, \\server\share, \\server\share} | |
@"//server/share", | |
// {true, \\server\share, \\server\share\file} | |
@"//server/share/file", | |
// {true, \\server\, \\server\file} | |
@"//server//file", | |
// {true, \\server\, \\server\file} | |
@"/\server//file", | |
// {true, \\.hidden\file, <unchanged>} | |
@"\\.hidden\file", | |
// {true, \\?question\file, <unchanged>} | |
@"\\?question\file", | |
}; | |
// DOS device path test cases: | |
static string[] devicePaths = { | |
// {true, \\.\volume\, <unchanged>} | |
@"\\.\volume\foo", | |
// {true, \\.\C:\, <unchanged>} | |
@"\\.\C:\Test\Foo.txt", | |
// {true, \\?\C:\, <unchanged>} | |
@"\\?\C:\Test\Foo.txt", | |
// {true, \\?\C$\, <unchanged>} | |
@"\\?\C$\Test\Foo.txt", | |
// {true, \\?\C:foo\, <unchanged>} | |
@"\\?\C:foo\Foo.txt", | |
// {true, \\?\C$foo\, <unchanged>} | |
@"\\?\C$foo\Foo.txt", | |
// {true, \\?\server1\, <unchanged>} | |
@"\\?\server1\e:\util\\file\", | |
// {true, \\?\server1\, <unchanged>} | |
@"\\?\server1\util\\file\", | |
// {true, \\?\server1\, <unchanged>} | |
@"\\?\server1\util\file\", | |
// {true, \\.\CON, <unchanged>} | |
@"\\.\CON", | |
// {true, \\.\CON\, <unchanged>} | |
@"\\.\CON\", | |
// {true, \\.\LPT1, <unchanged>} | |
@"\\.\LPT1", | |
// {true, \\.\COM1, <unchanged>} | |
@"\\.\COM1", | |
// {true, \\., \\.\} | |
@"\\.", | |
// {true, \\.\, <unchanged>} | |
@"\\.\", | |
// {true, \\.\vol, <unchanged>} | |
@"\\.\vol", | |
}; | |
// DOS device GUID-volume path test cases: | |
static string[] guidPaths = { | |
// {true, \\.\Volume{b75e2c83-0000-0000-0000-602f00000000}\, <unchanged>} | |
@"\\.\Volume{b75e2c83-0000-0000-0000-602f00000000}\Test\Foo.txt", | |
// {true, \\?\Volume{b75e2c83-0000-0000-0000-602f00000000}\, <unchanged>} | |
@"\\?\Volume{b75e2c83-0000-0000-0000-602f00000000}\Test\Foo.txt", | |
// {true, \\server\Volume{b75e2c83-0000-0000-0000-602f00000000}, <unchanged>} | |
@"\\server\Volume{b75e2c83-0000-0000-0000-602f00000000}\Test\Foo.txt", | |
// {true, \\.\UNC\server\Volume{b75e2c83-0000-0000-0000-602f00000000}, <unchanged>} | |
@"\\.\UNC\server\Volume{b75e2c83-0000-0000-0000-602f00000000}\Test\Foo.txt", | |
}; | |
// Legacy DOS device path test cases: | |
static string[] legacyDevicePaths = { | |
// {false, nil, \\.\CON} | |
@"CON", | |
// {false, nil, C:\Users\User\Documents\PathExplorer\CON\} | |
@"CON\", | |
// {false, nil, \\.\CON} | |
@"CON.TXT", | |
// {false, nil, C:\Users\User\Documents\PathExplorer\CON.TXT\} | |
@"CON.TXT\", | |
// {false, nil, C:\Users\User\Documents\PathExplorer\CON.TXT\FILE.TXT} | |
@"CON.TXT\FILE.TXT", | |
// {false, nil, \\.\LPT1} | |
@"LPT1", | |
// {false, nil, C:\Users\User\Documents\PathExplorer\LPT1\} | |
@"LPT1\", | |
// {false, nil, \\.\LPT1} | |
@"LPT1.TXT", | |
// {false, nil, C:\Users\User\Documents\PathExplorer\LPT1.TXT\} | |
@"LPT1.TXT\", | |
// {false, nil, \\.\LPT1} | |
@"LPT1.XTX", | |
// {false, nil, \\.\COM1} | |
@"COM1", | |
// {false, nil, C:\Users\User\Documents\PathExplorer\COM1\} | |
@"COM1\", | |
// {false, nil, \\.\COM1} | |
@"COM1.TXT", | |
// {false, nil, C:\Users\User\Documents\PathExplorer\COM1.TXT\} | |
@"COM1.TXT\", | |
// {false, nil, C:\Users\User\Documents\PathExplorer\CON1} | |
@"CON1", | |
// {false, nil, C:\Users\User\Documents\PathExplorer\LPT1\FILE.TXT} | |
@"LPT1\FILE.TXT", | |
// {false, nil, C:\Users\User\Documents\PathExplorer\COM} | |
@"COM", | |
// {false, nil, C:\Users\User\Documents\PathExplorer\COM1.TXT\FILE.TXT} | |
@"COM1.TXT\FILE.TXT", | |
}; | |
static void print(string content) { | |
Console.WriteLine(content.TrimEnd()); | |
} | |
// Print out the path test cases and associated output as source-idempotent code | |
static void printPathStats(string title, string name, string[] paths) { | |
int length = 0; | |
int rootLength = 0; | |
bool hasRelative = false; | |
foreach (string path in paths) { | |
length = Math.Max(length, path.Length); | |
rootLength = Math.Max(rootLength, path.Length > 0 ? Path.GetPathRoot(path).Length : 0); | |
hasRelative = hasRelative || !Path.IsPathFullyQualified(path); | |
} | |
print($"// {title} test cases:"); | |
print($"static string[] {name} = {'{'}"); | |
foreach (string path in paths) { | |
bool rooted = Path.IsPathRooted(path); | |
string pathRoot = Path.GetPathRoot(path); | |
bool fullyQualified = Path.IsPathFullyQualified(path); | |
Debug.Assert(rooted == (pathRoot != "" && pathRoot != null)); | |
string rootStr = rooted ? pathRoot : "nil"; | |
string qual = fullyQualified ? "true, " : "false, "; | |
string root = $"{rootStr}, {new string(' ', Math.Max(0, rootLength - rootStr.Length))}"; | |
string full = "<unchanged>"; | |
if (path != "") { | |
string fullPath = Path.GetFullPath(path); | |
if (path != fullPath) { | |
full = fullPath; | |
} | |
} | |
string prefix = $" @\"{path}\""; | |
string comment = $" // {{{qual}{root}{full}}}"; | |
string output = $"{prefix},{new string(' ', length - path.Length)}"; | |
print(comment); | |
print(output); | |
print(""); | |
} | |
print("};"); | |
print(""); | |
} | |
static void Main(string[] args) | |
{ | |
print("// Info: {fullyQualified, root, fullPath}"); | |
print(""); | |
printPathStats("Traditional path", "traditionalPaths", traditionalPaths); | |
printPathStats("UNC path", "uncPaths", uncPaths); | |
printPathStats("DOS device path", "devicePaths", devicePaths); | |
printPathStats("DOS device GUID-volume path", "guidPaths", guidPaths); | |
printPathStats("Legacy DOS device path", "legacyDevicePaths", legacyDevicePaths); | |
} | |
} } // namespace HelloWorld { class Program { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment