Pertanyaan Periksa apakah jalur lengkap diberikan


Apakah ada metode untuk memeriksa apakah jalur yang diberikan adalah jalur lengkap? Sekarang aku melakukan ini:

if (template.Contains(":\\")) //full path already given
{
}
else //calculate the path from local assembly
{
}

Tetapi harus ada cara yang lebih elegan untuk memeriksa ini?


75
2018-04-06 10:41


asal


Jawaban:


Coba gunakan System.IO.Path.IsPathRooted? Ia juga kembali true untuk jalur absolut.

System.IO.Path.IsPathRooted(@"c:\foo"); // true
System.IO.Path.IsPathRooted(@"\foo"); // true
System.IO.Path.IsPathRooted("foo"); // false

System.IO.Path.IsPathRooted(@"c:1\foo"); // surprisingly also true
System.IO.Path.GetFullPath(@"c:1\foo");// returns "[current working directory]\1\foo"

109
2018-04-06 10:43



Path.IsPathRooted(path)
&& !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)

Kondisi di atas:

  • tidak memerlukan izin sistem file
  • kembali false dalam banyak kasus di mana format path tidak valid (daripada melempar pengecualian)
  • kembali true hanya jika path termasuk volume

Dalam skenario seperti yang dilakukan OP, mungkin karena itu lebih cocok daripada kondisi dalam jawaban sebelumnya. Berbeda dengan kondisi di atas:

  • path == System.IO.Path.GetFullPath(path) melempar pengecualian daripada kembali false dalam skenario ini:
    • Penelepon tidak memiliki izin yang diperlukan
    • Sistem tidak dapat mengambil jalur absolut
    • path berisi titik dua (":") yang bukan bagian dari pengenal volume
    • Jalur yang ditentukan, nama file, atau keduanya melebihi panjang maksimum yang ditentukan sistem
  • System.IO.Path.IsPathRooted(path) kembali true jika path dimulai dengan pemisah direktori tunggal.

Akhirnya, di sini adalah metode yang membungkus kondisi di atas dan juga menutup kemungkinan pengecualian yang tersisa:

public static bool IsFullPath(string path) {
    return !String.IsNullOrWhiteSpace(path)
        && path.IndexOfAny(System.IO.Path.GetInvalidPathChars().ToArray()) == -1
        && Path.IsPathRooted(path)
        && !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal);
}

EDIT: EM0 membuat komentar yang bagus dan jawaban alternatif menangani kasus aneh seperti ini C: dan C:dir. Untuk membantu memutuskan bagaimana Anda mungkin ingin menangani jalur tersebut, Anda mungkin ingin melakukan penyelaman mendalam ke MSDN -> Aplikasi desktop Windows -> Mengembangkan -> Teknologi desktop -> Akses dan Penyimpanan Data -> Sistem File Lokal -> Manajemen file -> Tentang Manajemen File -> Membuat, Menghapus, dan Mempertahankan File -> Penamaan File, Jalur, dan Ruang Nama -> Jalur yang Penuh Kualifikasi vs. Relatif

Untuk fungsi Windows API yang memanipulasi file, nama file bisa sering   relatif terhadap direktori saat ini, sementara beberapa API memerlukan sepenuhnya   jalur yang berkualitas. Nama file relatif ke direktori saat ini jika itu   tidak dimulai dengan salah satu dari yang berikut:

  • Nama UNC dari format apa pun, yang selalu dimulai dengan dua karakter backslash ("\"). Untuk informasi lebih lanjut, lihat bagian selanjutnya.
  • Penentu disk dengan backslash, misalnya "C: \" atau "d: \".
  • Satu backslash, misalnya, "\ direktori" atau "\ file.txt". Ini juga disebut sebagai jalur absolut.

Jika nama file dimulai hanya dengan penunjuk disk tetapi bukan   backslash setelah titik dua, itu ditafsirkan sebagai jalur relatif ke   direktori saat ini di drive dengan surat yang ditentukan. Perhatikan itu   direktori saat ini mungkin atau mungkin bukan direktori root tergantung   pada apa yang diatur ke selama "perubahan direktori" terbaru   operasi pada disk itu. Contoh format ini adalah sebagai berikut:

  • "C: tmp.txt" mengacu pada file bernama "tmp.txt" di direktori saat ini di drive C.
  • "C: tempdir \ tmp.txt" merujuk ke file dalam subdirektori ke direktori saat ini di drive C.

[...]


16
2018-01-27 19:34



Mencoba

System.IO.Path.IsPathRooted(template)

Bekerja untuk jalur UNC serta yang lokal.

Misalnya.

Path.IsPathRooted(@"\\MyServer\MyShare\MyDirectory")  // returns true
Path.IsPathRooted(@"C:\\MyDirectory")  // returns true

14
2018-04-06 10:45



Pertanyaan lama, tetapi satu lagi jawaban yang berlaku. Jika Anda perlu memastikan volume disertakan dalam jalur lokal, Anda dapat menggunakan System.IO.Path.GetFullPath () seperti ini:

if (template == System.IO.Path.GetFullPath(template))
{
    ; //template is full path including volume or full UNC path
}
else
{
    if (useCurrentPathAndVolume)
        template = System.IO.Path.GetFullPath(template);
    else
        template = Assembly.GetExecutingAssembly().Location
}

10
2017-09-19 12:34



Membangun bendungJawabannya: ini tidak membuang untuk jalur yang tidak valid, tetapi juga mengembalikan false untuk jalur seperti "C:", "C: dirname" dan "\ path".

public static bool IsFullPath(string path)
{
    if (string.IsNullOrWhiteSpace(path) || path.IndexOfAny(Path.GetInvalidPathChars()) != -1 || !Path.IsPathRooted(path))
        return false;

    var pathRoot = Path.GetPathRoot(path);
    if (pathRoot.Length <= 2 && pathRoot != "/") // Accepts X:\ and \\UNC\PATH, rejects empty string, \ and X:, but accepts / to support Linux
        return false;

    return !(pathRoot == path && pathRoot.StartsWith("\\\\") && pathRoot.IndexOf('\\', 2) == -1); // A UNC server name without a share name (e.g "\\NAME") is invalid
}

Perhatikan bahwa ini mengembalikan hasil yang berbeda pada Windows dan Linux, mis. "/ path" adalah mutlak di Linux, tetapi tidak pada Windows.

Tes unit:

[Test]
public void IsFullPath()
{
    bool isWindows = Environment.OSVersion.Platform.ToString().StartsWith("Win"); // .NET Framework
    // bool isWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Windows); // .NET Core

    // These are full paths on Windows, but not on Linux
    TryIsFullPath(@"C:\dir\file.ext", isWindows);
    TryIsFullPath(@"C:\dir\", isWindows);
    TryIsFullPath(@"C:\dir", isWindows);
    TryIsFullPath(@"C:\", isWindows);
    TryIsFullPath(@"\\unc\share\dir\file.ext", isWindows);
    TryIsFullPath(@"\\unc\share", isWindows);

    // These are full paths on Linux, but not on Windows
    TryIsFullPath(@"/some/file", !isWindows);
    TryIsFullPath(@"/dir", !isWindows);
    TryIsFullPath(@"/", !isWindows);

    // Not full paths on either Windows or Linux
    TryIsFullPath(@"file.ext", false);
    TryIsFullPath(@"dir\file.ext", false);
    TryIsFullPath(@"\dir\file.ext", false);
    TryIsFullPath(@"C:", false);
    TryIsFullPath(@"C:dir\file.ext", false);
    TryIsFullPath(@"\dir", false); // An "absolute", but not "full" path

    // Invalid on both Windows and Linux
    TryIsFullPath(null, false, false);
    TryIsFullPath("", false, false);
    TryIsFullPath("   ", false, false);
    TryIsFullPath(@"C:\inval|d", false, false);
    TryIsFullPath(@"\\is_this_a_dir_or_a_hostname", false, false);
}

private static void TryIsFullPath(string path, bool expectedIsFull, bool expectedIsValid = true)
{
    Assert.AreEqual(expectedIsFull, PathUtils.IsFullPath(path), "IsFullPath('" + path + "')");

    if (expectedIsFull)
    {
        Assert.AreEqual(path, Path.GetFullPath(path));
    }
    else if (expectedIsValid)
    {
        Assert.AreNotEqual(path, Path.GetFullPath(path));
    }
    else
    {
        Assert.That(() => Path.GetFullPath(path), Throws.Exception);
    }
}

4
2017-11-30 09:24



Saya tidak begitu yakin dengan apa yang Anda maksud jalur penuh (meskipun dengan asumsi dari contoh yang Anda maksud non-relatif dari root dan seterusnya), Anda dapat menggunakan Path kelas untuk membantu Anda dalam bekerja dengan path filesystem fisik, yang harus melindungi Anda untuk sebagian besar kemungkinan.


0
2018-04-06 10:43



Ini adalah solusi yang saya gunakan

public static bool IsFullPath(string path)
{
    try
    {
        return Path.GetFullPath(path) == path;
    }
    catch
    {
        return false;
    }
}

Ia bekerja dengan cara berikut:

IsFullPath(@"c:\foo"); // true
IsFullPath(@"C:\foo"); // true
IsFullPath(@"c:\foo\"); // true
IsFullPath(@"c:/foo"); // false
IsFullPath(@"\foo"); // false
IsFullPath(@"foo"); // false
IsFullPath(@"c:1\foo\"); // false

0
2018-04-11 12:49



Untuk memeriksa apakah jalan itu sepenuhnya memenuhi syarat (MSDN):

public static bool IsPathFullyQualified(string path)
{
    var root = Path.GetPathRoot(path);
    return root.StartsWith(@"\\") || root.EndsWith(@"\");
}

Ini sedikit lebih sederhana dari apa yang sudah diajukan, dan itu masih mengembalikan false untuk jalur drive-relatif seperti C:foo. Logikanya didasarkan langsung pada definisi MSDN tentang "sepenuhnya memenuhi syarat", dan saya belum menemukan contoh yang salah tentang hal itu.


Namun menariknya. NET Core 2.1 tampaknya memiliki metode baru Path.IsPathFullyQualified yang menggunakan metode internal PathInternal.IsPartiallyQualified (lokasi tautan akurat pada 2018-04-17).

Untuk generasi mendatang dan self-containment yang lebih baik dari posting ini, inilah implementasi yang terakhir untuk referensi:

internal static bool IsPartiallyQualified(ReadOnlySpan<char> path)
{
    if (path.Length < 2)
    {
        // It isn't fixed, it must be relative.  There is no way to specify a fixed
        // path with one character (or less).
        return true;
    }

    if (IsDirectorySeparator(path[0]))
    {
        // There is no valid way to specify a relative path with two initial slashes or
        // \? as ? isn't valid for drive relative paths and \??\ is equivalent to \\?\
        return !(path[1] == '?' || IsDirectorySeparator(path[1]));
    }

    // The only way to specify a fixed path that doesn't begin with two slashes
    // is the drive, colon, slash format- i.e. C:\
    return !((path.Length >= 3)
        && (path[1] == VolumeSeparatorChar)
        && IsDirectorySeparator(path[2])
        // To match old behavior we'll check the drive character for validity as the path is technically
        // not qualified if you don't have a valid drive. "=:\" is the "=" file's default data stream.
        && IsValidDriveChar(path[0]));
}

0
2018-04-17 16:47