Skip to content

[API Proposal]: Path.NormalizePath(string path, bool includeDirectorySeparator) #121052

Description

@ericstj

Background and motivation

I see a lot of folks implementing their own path normalization schemes so that they can compare paths as strings. Its understood that this does not handle symlinks or hardlinks - there are other methods for that.

Just search the codebase for normalizepath to see all the instances https://source.dot.net/#q=[NormalizePath](https://source.dot.net/#q=NormalizePath)

I recently addressed a bug in one implementation where we assumed TrimEndingDirectorySeparator would trim all separators but it only trims one.
microsoft/component-detection#1475

Simply trimming doesn't work since it doesn't handle the root separator.
Using GetFullPath doesn't work since it leaks the working directory for non-rooted paths.
Multiple directory separators need to be resolved to a single one, and normalized on the default separator.
Relative portions need to be removed when possible.

API Proposal

namespace System.IO;

public static class Path
{
    public string NormalizePath(string Path, bool includeDirectorySeparator = false);
}

API Usage

var normalized1 = Path.Normalize(path1);
var normalized2 = Path.Normalize(path2);
var samePath = normalized1 == normalized2;

Alternative Designs

GetFullPath - leaks working directory, expensive.
Resolve to physical file, get normalized path from filesystem - same drawbacks as GetFullPath plus it requires a resolvable path which may not be the case for diagnostic scenarios.

Risks

Callers need to understand that even different normalized paths might point to the same object due to symlinks, hardlinks, mounted file-systems, network shares, etc.

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-suggestionEarly API idea and discussion, it is NOT ready for implementationarea-System.IOuntriagedNew issue has not been triaged by the area owner

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions