Überprüfen Sie, ob ein Pfad gültig ist


110

Ich frage mich nur: Ich suche nach einer Möglichkeit zu überprüfen, ob ein bestimmter Pfad gültig ist. (Anmerkung: Ich will nicht , um zu überprüfen , ob eine Datei vorhanden ist Ich möchte nur den Nachweis der Gültigkeit des Wegs - Also , wenn eine Datei konnte existiert möglicherweise an der Stelle!) .

Das Problem ist, dass ich in der .NET-API nichts finden kann. Aufgrund der vielen Formate und Speicherorte, die Windows unterstützt, würde ich lieber etwas MS-natives verwenden.

Da sollte die Funktion in der Lage sein, zu überprüfen gegen:

  • Relative Pfade (./)
  • Absolute Pfade (c: \ tmp)
  • UNC-Pfade (\ some-pc \ c $)
  • NTFS-Einschränkungen wie der vollständige Pfad 1024 Zeichen - Wenn ich mich nicht irre, überschreitet der Pfad eine Datei, auf die für viele interne Windows-Funktionen nicht zugegriffen werden kann. Das Umbenennen mit dem Explorer funktioniert weiterhin
  • Volume-GUID-Pfade: "\? \ Volume {GUID} \ somefile.foo

Hat jemand eine solche Funktion?


Antworten:


58

Versuchen Sie Uri.IsWellFormedUriString():

  • Die Zeichenfolge wird nicht korrekt maskiert.

    http://www.example.com/path???/file name
  • Die Zeichenfolge ist eine absolute Uri, die eine implizite Datei Uri darstellt.

    c:\\directory\filename
  • Die Zeichenfolge ist eine absolute URI, bei der ein Schrägstrich vor dem Pfad fehlt.

    file://c:/directory/filename
  • Die Zeichenfolge enthält nicht entkoppelte Schrägstriche, auch wenn sie als Schrägstriche behandelt werden.

    http:\\host/path/file
  • Die Zeichenfolge stellt ein hierarchisches absolutes Uri dar und enthält kein ": //".

    www.example.com/path/file
  • Der Parser für das Uri.Scheme zeigt an, dass die ursprüngliche Zeichenfolge nicht gut geformt war.

    The example depends on the scheme of the URI.

9
Dies gibt false für zurück @"foo\bar\baz", was ein vollkommen gültiger relativer Pfad ist ...
Thomas Levesque

5
Thomas: Welche UriKind haben Sie angegeben? Sie können Absolute, Relative oder AbsoluteOrRelative verwenden.
Dan Gøran Lunde

1
Selbst mit UriKind als Relative oder AbsoluteOrRelative funktionierte es nicht für relative Pfade, wie Thomas es erwähnte. Ich habe stattdessen Patkos Antwort verwendet und sie funktioniert für meine Zwecke.
JohnnyM

1
Ich habe festgestellt, dass ein Pfad wie \\ Computername \ Verzeichnisname mit Leerzeichen \ Dateiname bei Verwendung von IsWellFormedUriString eine Ausnahme auslöst (entgegen meiner ursprünglichen Erwartung), da die Leerzeichen nicht ordnungsgemäß codiert sind. Ich stellte fest, dass ich nur den Uri-Konstruktor (Zeichenfolge) als Validierung verwenden konnte, wodurch die Zeichenfolge vor der Validierung nicht ordnungsgemäß codiert werden musste.
Quintessenz5

3
Gibt false für einen einwandfreien Dateipfad zurück.
Evgeni Petrov


7
private bool IsValidPath(string path)
{
    Regex driveCheck = new Regex(@"^[a-zA-Z]:\\$");
    if (!driveCheck.IsMatch(path.Substring(0, 3))) return false;
    string strTheseAreInvalidFileNameChars = new string(Path.GetInvalidPathChars());
    strTheseAreInvalidFileNameChars += @":/?*" + "\"";
    Regex containsABadCharacter = new Regex("[" + Regex.Escape(strTheseAreInvalidFileNameChars) + "]");
    if (containsABadCharacter.IsMatch(path.Substring(3, path.Length - 3)))
        return false;

    DirectoryInfo dir = new DirectoryInfo(Path.GetFullPath(path));
    if (!dir.Exists)
        dir.Create();
    return true;
}

7

Ich hatte keine Probleme mit dem folgenden Code. (Relative Pfade müssen mit '/' oder '\' beginnen).

private bool IsValidPath(string path, bool allowRelativePaths = false)
{
    bool isValid = true;

    try
    {
        string fullPath = Path.GetFullPath(path);

        if (allowRelativePaths)
        {
            isValid = Path.IsPathRooted(path);
        }
        else
        {
            string root = Path.GetPathRoot(path);
            isValid = string.IsNullOrEmpty(root.Trim(new char[] { '\\', '/' })) == false;
        }
    }
    catch(Exception ex)
    {
        isValid = false;
    }

    return isValid;
}

Zum Beispiel würden diese false zurückgeben:

IsValidPath("C:/abc*d");
IsValidPath("C:/abc?d");
IsValidPath("C:/abc\"d");
IsValidPath("C:/abc<d");
IsValidPath("C:/abc>d");
IsValidPath("C:/abc|d");
IsValidPath("C:/abc:d");
IsValidPath("");
IsValidPath("./abc");
IsValidPath("./abc", true);
IsValidPath("/abc");
IsValidPath("abc");
IsValidPath("abc", true);

Und diese würden wahr zurückkehren:

IsValidPath(@"C:\\abc");
IsValidPath(@"F:\FILES\");
IsValidPath(@"C:\\abc.docx\\defg.docx");
IsValidPath(@"C:/abc/defg");
IsValidPath(@"C:\\\//\/\\/\\\/abc/\/\/\/\///\\\//\defg");
IsValidPath(@"C:/abc/def~`!@#$%^&()_-+={[}];',.g");
IsValidPath(@"C:\\\\\abc////////defg");
IsValidPath(@"/abc", true);
IsValidPath(@"\abc", true);

3

Sie können diesen Code ausprobieren:

try
{
  Path.GetDirectoryName(myPath);
}
catch
{
  // Path is not valid
}

Ich bin nicht sicher, ob es alle Fälle abdeckt ...


2

Am nächsten bin ich gekommen, indem ich versucht habe, es zu erschaffen und zu sehen, ob es gelingt.


2

Hier gibt es viele gute Lösungen, aber da keiner von ihnen prüft, ob der Pfad in einem vorhandenen Laufwerk verwurzelt ist, ist hier ein anderer:

private bool IsValidPath(string path)
{
    // Check if the path is rooted in a driver
    if (path.Length < 3) return false;
    Regex driveCheck = new Regex(@"^[a-zA-Z]:\\$");
    if (!driveCheck.IsMatch(path.Substring(0, 3))) return false;

    // Check if such driver exists
    IEnumerable<string> allMachineDrivers = DriveInfo.GetDrives().Select(drive => drive.Name);
    if (!allMachineDrivers.Contains(path.Substring(0, 3))) return false;

    // Check if the rest of the path is valid
    string InvalidFileNameChars = new string(Path.GetInvalidPathChars());
    InvalidFileNameChars += @":/?*" + "\"";
    Regex containsABadCharacter = new Regex("[" + Regex.Escape(InvalidFileNameChars) + "]");
    if (containsABadCharacter.IsMatch(path.Substring(3, path.Length - 3)))
        return false;
    if (path[path.Length - 1] == '.') return false;

    return true;
}

Diese Lösung berücksichtigt keine relativen Pfade.


1

Holen Sie sich die ungültigen Zeichen von System.IO.Path.GetInvalidPathChars();und prüfen Sie, ob Ihre Zeichenfolge (Verzeichnispfad) diese enthält oder nicht.


3
Dies ist nicht ganz gültig. "C: \ new.folder" ist gültig, während "C: \ newfolder" gültig ist. ist nicht. '.' ist ein gültiges Zeichen für einen Pfad / Dateinamen, jedoch nicht am Ende des Uri.
Cladekennilol

0

4
"[...] möchte nicht überprüfen, ob eine Datei vorhanden ist!"
Stefan

3
Dieser Test für das vorhandene Verzeichnis, nicht für einen gültigen Pfad (wo einer vorhanden sein könnte oder erstellt werden könnte, wenn die entsprechenden Berechtigungen vorliegen)
Martijn

3
@Jason - Es wird nicht die Datei überprüft, sondern nur der enthaltende Ordner.
Markpsmith

8
Ein gültiger Verzeichnispfad konnte jedoch noch nicht vorhanden sein.
Stefan

-2
private bool IsValidPath(string path)
{
    Regex driveCheck = new Regex(@"^[a-zA-Z]:\\$");

    if (string.IsNullOrWhiteSpace(path) || path.Length < 3)
    {
        return false;
    }

    if (!driveCheck.IsMatch(path.Substring(0, 3)))
    {
        return false;
    }

    var x1 = (path.Substring(3, path.Length - 3));
    string strTheseAreInvalidFileNameChars = new string(Path.GetInvalidPathChars());
    strTheseAreInvalidFileNameChars += @":?*";
    Regex containsABadCharacter = new Regex("[" + Regex.Escape(strTheseAreInvalidFileNameChars) + "]");

    if (containsABadCharacter.IsMatch(path.Substring(3, path.Length - 3)))
    {
        return false;
    }

    var driveLetterWithColonAndSlash = Path.GetPathRoot(path);

    if (!DriveInfo.GetDrives().Any(x => x.Name == driveLetterWithColonAndSlash))
    {
        return false;
    }

    return true;
}

1
Was ist der Zweck von x1?
JayJay


-4

Sie können versuchen, Path.IsPathRooted () in Kombination mit Path.GetInvalidFileNameChars () zu verwenden, um sicherzustellen, dass der Pfad zur Hälfte in Ordnung ist.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.