Bir yolun geçerli olup olmadığını kontrol edin


110

Sadece merak ediyorum: Verilen bir yolun geçerli olup olmadığını doğrulamanın bir yolunu arıyorum. (Not: Bir dosyanın mevcut olup olmadığını kontrol etmek istemiyorum! Yalnızca yolun geçerliliğini kanıtlamak istiyorum - Yani, konumda bir dosya varsa) .

Sorun şu ki, .Net API'de hiçbir şey bulamıyorum. Windows'un desteklediği birçok biçim ve konum nedeniyle, MS'e özgü bir şey kullanmayı tercih ederim.

İşlev aşağıdakilere karşı kontrol yapabilmesi gerektiğinden:

  • Göreli Yollar (./)
  • Mutlak Yollar (c: \ tmp)
  • UNC-Yolları (\ bir-bilgisayar \ c $)
  • Tam yol 1024 karakter gibi NTFS-Sınırlamaları - Hatalı değilsem, yolun aşılması, bir dosyayı birçok dahili Windows işlevi için erişilemez hale getirir. Explorer ile yeniden adlandırmak hala çalışıyor
  • Birim GUID Yolları: "\? \ Volume {GUID} \ somefile.foo

Böyle bir işlevi olan var mı?


Yanıtlar:


58

Deneyin Uri.IsWellFormedUriString():

  • Dize doğru şekilde öncelenmemiş.

    http://www.example.com/path???/file name
  • Dize, örtük bir dosya Uri'yi temsil eden mutlak bir URI'dır.

    c:\\directory\filename
  • Dize, yoldan önce eğik çizgisi olmayan mutlak bir URI'dır.

    file://c:/directory/filename
  • Dize, eğik çizgi olarak değerlendirilseler bile, çıkış karakteri olmayan ters eğik çizgiler içerir.

    http:\\host/path/file
  • Dize, hiyerarşik bir mutlak URI'yı temsil eder ve ": //" içermez.

    www.example.com/path/file
  • Uri.Scheme için ayrıştırıcı, orijinal dizenin iyi biçimlendirilmediğini gösterir.

    The example depends on the scheme of the URI.

9
Bu @"foo\bar\baz", tamamen geçerli bir göreceli yol olan için yanlış döndürür ...
Thomas Levesque 18'12

5
Thomas: Hangi UriKind'i belirttin? Mutlak, Göreli veya Mutlak veya Göreceli kullanabilirsiniz.
Dan Gøran Lunde

1
Göreceli veya Mutlak veya Bağıl olarak UriKind olsa bile, Thomas'ın bahsettiği gibi göreli yollar için işe yaramadı. Bunun yerine Patko'nun cevabını kullandım ve amaçlarım için çalışıyor.
JohnnyM

1
\\ computerName \ Dir Name With Spaces \ fileName gibi bir yolun IsWellFormedUriString kullanılırken bir istisna attığını buldum (ilk beklentimin aksine), çünkü boşluklar düzgün şekilde kodlanmamış. Doğrulamam olarak sadece Uri (string) yapıcısını kullanabileceğimi, dolayısıyla doğrulamadan önce dizeyi düzgün şekilde kodlamak zorunda kalmayacağımı buldum.
quintessential5

3
Mükemmel derecede ince bir dosya yolunda yanlış döndürür.
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

Aşağıdaki kodla herhangi bir sorun yaşamadım. (Göreli yollar "/" veya "\" ile başlamalıdır).

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

Örneğin bunlar yanlış döndürür:

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

Ve bunlar doğru olacaktır:

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

Bu kodu deneyebilirsiniz:

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

Tüm davaları kapsadığından emin değilim ...


2

En yakın geldim, onu yaratmaya çalışmak ve başarılı olup olmadığını görmek.


2

Burada pek çok iyi çözüm var, ancak hiçbiri yolun mevcut bir sürücüde köklü olup olmadığını kontrol etmediğiniz için işte bir tane daha:

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

Bu çözüm yok değil dikkate göreli yollar alır.


1

Geçersiz karakterleri alın System.IO.Path.GetInvalidPathChars();ve dizenizin (Dizin yolu) bunları içerip içermediğini kontrol edin.


3
Bu tamamen geçerli değil. "C: \ new.folder", "C: \ newfolder" ise geçerlidir. değil. "." bir yollar / dosya adları için geçerli bir karakterdir, ancak uri'nin sonunda değildir.
claudekennilol

0

4
"[...] bir dosyanın mevcut olup olmadığını kontrol etmek istemiyorum!"
Stefan

3
Mevcut dizin için bu test, geçerli bir yol olmadığı için değil (birinin var olabileceği veya uygun ayrıcalıkların verildiği yerlerde)
Martijn

3
@Jason - Dosyayı kontrol etmez, sadece içerdiği klasörü kontrol eder.
markpsmith

8
ancak geçerli bir dizin yolu hala mevcut olamaz.
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
x1'in amacı nedir?
JayJay


-4

Yolun yarı yolda olduğundan emin olmak için Path.IsPathRooted () ile Path.GetInvalidFileNameChars () kombinasyonunu kullanmayı deneyebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.