<p>Does anyone know of any good library that abstracts the problem of path manipulation in a nice way? I'd like to be able to combine and parse paths with arbitrary separators ('/' or ':' for example) without reinventing the wheel.</p>

<p>It's a shame that <code>System.IO.Path</code> isn't more reusable.</p>

<p>Thanks</p>

[{'answer_id': 52074, 'author': 'Espo', 'author_id': 2257, 'author_profile': 'https://Stackoverflow.com/users/2257', 'pm_score': 1, 'selected': False, 'text': '<p>System.IO.Path.Combine will work great for many different types of paths:</p>\n\n<p><a href="http://msdn.microsoft.com/en-us/library/system.io.path.combine.aspx" rel="nofollow noreferrer">http://msdn.microsoft.com/en-us/library/system.io.path.combine.aspx</a></p>\n\n<p>System.IO.Path.Combine uses the current platform standard separators to combine paths. That means on Windows it uses "\\" and on unix/linux (mono) it uses "/". Can you give some samples of what paths you are trying to combine and on what platform?</p>\n'}, {'answer_id': 52117, 'author': 'rp.', 'author_id': 2536, 'author_profile': 'https://Stackoverflow.com/users/2536', 'pm_score': 0, 'selected': False, 'text': "<p>You're describing regular expressions! Use that as the underpinning for what you need to do. </p>\n"}, {'answer_id': 55305, 'author': 'Aaron Fischer', 'author_id': 5618, 'author_profile': 'https://Stackoverflow.com/users/5618', 'pm_score': 1, 'selected': False, 'text': '<p>Check Patrick\'s library to handle path operations <a href="http://codebetter.com/blogs/patricksmacchia/archive/2007/10/18/a-free-library-to-handle-common-path-operation.aspx" rel="nofollow noreferrer">link text</a></p>\n\n<p>This is the <a href="http://www.codeplex.com/FileDirectoryPath" rel="nofollow noreferrer">codeplex project</a></p>\n'}, {'answer_id': 1637777, 'author': 'Bob', 'author_id': 45, 'author_profile': 'https://Stackoverflow.com/users/45', 'pm_score': 0, 'selected': False, 'text': '<p>I can\'t tell what environment you might be using based off of your separators, but I have never seen a library like this before.</p>\n\n<p>So using reflector and <code>System.IO.Path</code> as a basis it isn\'t difficult to reinvent the wheel. </p>\n\n<ul>\n<li>Create an instance of this class </li>\n<li>Supply your separator characters in the CTor</li>\n<li>Optionally change the <code>InvalidPathChars</code> if needed. </li>\n</ul>\n\n<p>This is pretty much the code that is used by the framework so it should be just as fast or only a negligible difference. May or may not be faster than RegEx, it is probably worth a test though. </p>\n\n<pre><code>class ArbitraryPath\n{\n    private readonly char _directorySeparatorChar;\n    private readonly char _altDirectorySeparatorChar;\n    private readonly char _volumeSeparatorChar;\n\n    public ArbitraryPath(char directorySeparatorChar, char altDirectorySeparatorChar, char volumeSeparatorChar)\n    {\n        _directorySeparatorChar = directorySeparatorChar;\n        _altDirectorySeparatorChar = altDirectorySeparatorChar;\n        _volumeSeparatorChar = volumeSeparatorChar;\n    }\n\n    public string Combine(string path1, string path2)\n    {\n        if ((path1 == null) || (path2 == null))\n        {\n            throw new ArgumentNullException((path1 == null) ? "path1" : "path2");\n        }\n        CheckInvalidPathChars(path1);\n        CheckInvalidPathChars(path2);\n        if (path2.Length == 0)\n        {\n            return path1;\n        }\n        if (path1.Length == 0)\n        {\n            return path2;\n        }\n        if (IsPathRooted(path2))\n        {\n            return path2;\n        }\n\n        char ch = path1[path1.Length - 1];\n        if (ch != _directorySeparatorChar &amp;&amp; ch != _altDirectorySeparatorChar &amp;&amp; ch != _volumeSeparatorChar)\n        {\n            return (path1 + _directorySeparatorChar + path2);\n        }\n        return (path1 + path2);\n    }\n\n    public bool IsPathRooted(string path)\n    {\n        if (path != null)\n        {\n            CheckInvalidPathChars(path);\n            int length = path.Length;\n            if (length &gt;= 1 &amp;&amp; (path[0] == _directorySeparatorChar || path[0] == _altDirectorySeparatorChar) || length &gt;= 2 &amp;&amp; path[1] == _volumeSeparatorChar)\n            {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    internal static void CheckInvalidPathChars(string path)\n    {\n        for (int i = 0; i &lt; path.Length; i++)\n        {\n            int num2 = path[i];\n            if (num2 == 0x22 || num2 == 60 || num2 == 0x3e || num2 == 0x7c || num2 &lt; 0x20)\n            {\n                throw new ArgumentException("Argument_InvalidPathChars");\n            }\n        }\n    } \n\n}\n</code></pre>\n'}, {'answer_id': 3677449, 'author': 'Dimitri C.', 'author_id': 74612, 'author_profile': 'https://Stackoverflow.com/users/74612', 'pm_score': 0, 'selected': False, 'text': '<p>I\'m afraid <a href="https://stackoverflow.com/questions/2026302/is-there-a-class-for-holding-a-file-system-path">you\'ll have to implement a path class yourself</a>, as I did. It gives the following advantages:</p>\n\n<ul>\n<li>you can profit from type safety</li>\n<li>you can override operator/, which makes concatenation easier</li>\n<li>you can add convenience member functions such as GetParentPath() and GetLeafPart()</li>\n</ul>\n'}]
['https://Stackoverflow.com/questions/52071', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/5380/']