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?

Tobias Boschek
sumber

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.
abatishchev
sumber
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;
}
Alex Jolig
sumber
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);
Dao Seeker
sumber
3

Anda dapat mencoba kode ini:

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

Saya tidak yakin itu mencakup semua kasus ...

Nimrod
sumber
2

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

Martijn
sumber
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.

Gark Garcia
sumber
1

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

Umesh CHILAKA
sumber
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

Directory.Exists?

markpsmith
sumber
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;
}
Ghislain Zabatio
sumber
1
apa tujuan x1?
JayJay
-3

Cukup Gunakan

if (System.IO.Directory.Exists(path))
{
    ...
}
Mahdi Astanei
sumber
-4

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

Alen Milakovic
sumber