Periksa apakah jalur valid


110

Saya hanya bertanya-tanya: Saya sedang mencari cara untuk memvalidasi jika jalur yang diberikan valid. (Catatan: Saya tidak ingin memeriksa apakah ada file! Saya hanya ingin membuktikan keabsahan jalur - Jadi jika file mungkin ada di lokasi) .

Masalahnya, saya tidak dapat menemukan apa pun di .Net API. Karena banyaknya format dan lokasi yang didukung Windows, saya lebih suka menggunakan sesuatu yang asli MS.

Karena fungsi tersebut harus dapat memeriksa:

  • Jalur Relatif (./)
  • Jalur Mutlak (c: \ tmp)
  • Jalur UNC (\ some-pc \ c $)
  • NTFS-Batasan seperti jalur lengkap 1024 karakter - Jika saya tidak salah melebihi jalur akan membuat file tidak dapat diakses untuk banyak fungsi Windows internal. Mengganti nama dengan Explorer masih berfungsi
  • Jalur GUID Volume: "\? \ Volume {GUID} \ somefile.foo

Apakah ada yang punya fungsi seperti ini?


Jawaban:


58

Coba Uri.IsWellFormedUriString():

  • String tidak lolos dengan benar.

    http://www.example.com/path???/file name
  • String adalah Uri absolut yang merepresentasikan file Uri implisit.

    c:\\directory\filename
  • String adalah URI absolut yang tidak memiliki garis miring sebelum jalur.

    file://c:/directory/filename
  • String tersebut berisi garis miring terbalik yang tidak dapat lolos meskipun diperlakukan sebagai garis miring ke depan.

    http:\\host/path/file
  • String mewakili Uri absolut hierarkis dan tidak berisi ": //".

    www.example.com/path/file
  • Parser untuk Uri.Scheme menunjukkan bahwa string asli tidak dibentuk dengan baik.

    The example depends on the scheme of the URI.

9
Ini mengembalikan false untuk @"foo\bar\baz", yang merupakan jalur relatif yang benar-benar valid ...
Thomas Levesque

5
Thomas: UriKind apa yang Anda sebutkan? Anda dapat menggunakan Absolute, Relative atau AbsoluteOrRelative.
Dan Gøran Lunde

1
Bahkan dengan UriKind sebagai Relative atau AbsoluteOrRelative, itu tidak berfungsi untuk jalur relatif seperti yang disebutkan Thomas. Saya akhirnya menggunakan jawaban Patko sebagai gantinya & itu berfungsi untuk tujuan saya.
JohnnyM

1
Saya menemukan bahwa jalur seperti \\ computerName \ Dir Name With Spaces \ fileName memunculkan pengecualian saat menggunakan IsWellFormedUriString (bertentangan dengan harapan awal saya), karena spasi tidak dikodekan dengan benar. Saya menemukan bahwa saya hanya dapat menggunakan konstruktor Uri (string) sebagai validasi saya, dengan demikian, tidak harus menyandikan string dengan benar sebelum memvalidasi.
klasik 5

3
Mengembalikan nilai salah pada jalur file yang sangat bagus.
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

Saya tidak mengalami masalah dengan kode di bawah ini. (Jalur relatif harus dimulai dengan '/' atau '\').

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;
}

Misalnya, ini akan mengembalikan false:

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);

Dan ini akan kembali benar:

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

Anda dapat mencoba kode ini:

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

Saya tidak yakin itu mencakup semua kasus ...


2

Yang paling dekat saya datang adalah dengan mencoba membuatnya, dan melihat apakah itu berhasil.


2

Ada banyak solusi bagus di sini, tetapi karena tidak ada yang memeriksa apakah jalurnya di-root pada drive yang ada, inilah yang lain:

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;
}

Solusi ini tidak memperhitungkan jalur relatif.


1

Dapatkan karakter yang tidak valid dari System.IO.Path.GetInvalidPathChars();dan periksa apakah string Anda (jalur Direktori) berisi karakter tersebut atau tidak.


3
Ini tidak sepenuhnya valid. "C: \ new.folder" valid sementara "C: \ newfolder". tidak. '.' adalah karakter yang valid untuk jalur / nama file, tetapi tidak di akhir uri.
claudekennilol

0

4
"[...] tidak ingin memeriksa apakah ada file!"
Stefan

3
Tes itu untuk direktori yang ada, bukan karena itu jalur yang valid (di mana mungkin ada, atau dibuat, diberi hak istimewa yang tepat)
Martijn

3
@Jason - Ini tidak memeriksa file, hanya folder yang berisi.
markpsmith

8
tetapi jalur direktori yang valid masih belum ada.
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
apa tujuan x1?
JayJay


-4

Anda bisa mencoba menggunakan Path.IsPathRooted () dalam kombinasi dengan Path.GetInvalidFileNameChars () untuk memastikan jalurnya sudah setengah jalan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.