PathLib.Sharp is a C# library that mimics the functionality and API design of Python's pathlib module. It provides an object-oriented approach to filesystem path operations, making path handling more intuitive and safer than traditional string manipulation.
- Multiple path construction options
- Automatic handling of platform-specific path separators
- Path join operator (
/) - Implicit string conversion
Parts- Array of path componentsName- File name (including extension)Stem- File name without extensionSuffix- File extensionSuffixes- All extensions (supports compound extensions like.tar.gz)Parent- Parent directoryParents- All ancestor directoriesDrive- Drive letter (Windows)Root- Root pathAnchor- Drive + root path
JoinPath()- Concatenate path segmentsWithName()- Return path with a different file nameWithStem()- Return path with a different stemWithSuffix()- Return path with a different extensionAbsolute()- Get the absolute pathResolve()- Resolve the path (handles symlinks)IsAbsolute- Whether the path is absolute
Exists- Whether the path existsIsFile- Whether the path is a fileIsDirectory- Whether the path is a directoryIsSymlink- Whether the path is a symbolic linkStat()- Get filesystem metadata
Open()- Open a file streamReadText()/WriteText()- Read/write text filesReadBytes()/WriteBytes()- Read/write binary filesTouch()- Create an empty file or update its modification time
IterateDirectory()- Iterate over directory contentsGlob()- Pattern-based file searchRecursiveGlob()- Recursive pattern matchingMakeDirectory()- Create a directoryRemoveDirectory()- Remove an empty directory
Rename()- Rename / move a pathReplace()- Replace a path (force overwrite)Unlink()- Delete a fileSymlinkTo()- Create a symbolic link
SharpPath.CurrentDirectory- Current working directorySharpPath.Home- User home directory
using PathLib;
// Create a path
var path = new SharpPath("documents", "projects", "myfile.txt");
Console.WriteLine(path); // documents\projects\myfile.txt (Windows)
// Path properties
Console.WriteLine($"Name: {path.Name}"); // myfile.txt
Console.WriteLine($"Stem: {path.Stem}"); // myfile
Console.WriteLine($"Suffix: {path.Suffix}"); // .txt
Console.WriteLine($"Parent: {path.Parent}"); // documents\projectsvar basePath = new SharpPath("C:", "Users");
var fullPath = basePath / "username" / "Documents" / "file.txt";
// C:\Users\username\Documents\file.txtvar originalPath = new SharpPath("document.pdf");
var withNewName = originalPath.WithName("report.pdf"); // report.pdf
var withNewStem = originalPath.WithStem("backup"); // backup.pdf
var withNewExt = originalPath.WithSuffix(".txt"); // document.txtvar textFile = new SharpPath("example.txt");
// Write to file
textFile.WriteText("Hello, PathLib.Sharp!");
// Read from file
string content = textFile.ReadText();
// Inspect the file
if (textFile.Exists && textFile.IsFile)
{
Console.WriteLine($"File size: {textFile.Stat()?.Length} bytes");
}var directory = new SharpPath("my_folder");
// Create directory
directory.MakeDirectory();
// Iterate directory
foreach (var item in directory.IterateDirectory())
{
if (item.IsFile)
Console.WriteLine($"File: {item.Name}");
else if (item.IsDirectory)
Console.WriteLine($"Directory: {item.Name}");
}
// Pattern matching
var txtFiles = directory.Glob("*.txt");// Recursively search for all C# files
var projectDir = new SharpPath("my_project");
var csFiles = projectDir.Glob("**/*.cs");
// Create a symbolic link
var target = new SharpPath("original_file.txt");
var link = new SharpPath("link_to_file.txt");
link.SymlinkTo(target);
// Safe file deletion
var tempFile = new SharpPath("temp.log");
tempFile.Unlink(missingOk: true); // Does not throw if file is missing- ✅ Windows (.NET 8.0+)
- ✅ Linux (.NET 8.0+)
- ✅ macOS (.NET 8.0+)
| Python pathlib | PathLib.Sharp | Description |
|---|---|---|
Path('a', 'b') |
new SharpPath("a", "b") |
Path construction |
path / 'subdir' |
path / "subdir" |
Path joining |
path.name |
path.Name |
File name |
path.stem |
path.Stem |
File stem |
path.suffix |
path.Suffix |
Extension |
path.parent |
path.Parent |
Parent directory |
path.exists() |
path.Exists |
Existence check |
path.is_file() |
path.IsFile |
File check |
path.read_text() |
path.ReadText() |
Read text |
path.glob('*.txt') |
path.Glob("*.txt") |
Pattern matching |
Install via NuGet:
dotnet add package CodeWine.PathLib.SharpOr build from source:
# Clone the repository
git clone https://github.com/BYJRK/PathLib.Sharp
cd PathLib.Sharp
# Build
dotnet build
# Run tests
dotnet test
# Pack NuGet package
dotnet packThe project contains 66 test cases covering:
- ✅ Constructor tests (4 tests)
- ✅ Property access tests (11 tests)
- ✅ Operator overload tests (4 tests)
- ✅ Path manipulation tests (6 tests)
- ✅ Filesystem query tests (4 tests)
- ✅ File operation tests (6 tests)
- ✅ Directory operation tests (6 tests)
- ✅ Filesystem operation tests (5 tests)
- ✅ Static method tests (2 tests)
- ✅ Equality and comparison tests (5 tests)
- ✅ Wildcard matching tests (5 tests)
- ✅ Edge cases and error handling tests (8 tests)
Contributions are welcome! Feel free to open a Pull Request or create an Issue to report bugs or suggest new features.
- Path operations follow the conventions of the current operating system
- Path comparisons are case-insensitive on Windows and case-sensitive on Unix/Linux
- Symbolic link operations require appropriate system permissions
- Some operations may fail due to filesystem permissions — handle exceptions accordingly