Jawaban:
Coba gunakan System.IO.Path.IsPathRooted
? Itu 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"
IsPathRooted
: menghindari mengakses sistem file atau memberikan pengecualian untuk input yang tidak valid.
IsPathRooted
, tentu saja tidak ada yang signifikan. The GetFullPath
garis termasuk sehingga jalan sedang dievaluasi dapat diamati
Path.IsPathRooted(path)
&& !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)
Kondisi diatas:
false
dalam banyak kasus di mana format path
tidak valid (daripada melempar pengecualian)true
hanya jika path
menyertakan volumeDalam skenario seperti yang diajukan OP, oleh karena itu mungkin lebih cocok daripada kondisi pada jawaban sebelumnya. Berbeda dengan kondisi diatas:
path == System.IO.Path.GetFullPath(path)
melempar pengecualian daripada kembali false
dalam skenario ini:
System.IO.Path.IsPathRooted(path)
kembali true
jika path
dimulai dengan pemisah direktori tunggal.Terakhir, berikut 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 yang menangani kasus aneh jalur seperti C:
dan C:dir
. Untuk membantu memutuskan bagaimana Anda mungkin ingin menangani jalur tersebut, Anda mungkin ingin mempelajari MSDN -> aplikasi desktop Windows -> Kembangkan -> Teknologi desktop -> Akses dan Penyimpanan Data -> Sistem File Lokal - -> Manajemen File -> Tentang Manajemen File -> Membuat, Menghapus, dan Memelihara File -> Menamai File, Jalur, dan Namespaces -> Jalur Berkualifikasi Penuh vs. Relatif
Untuk fungsi Windows API yang memanipulasi file, nama file sering kali dapat dikaitkan dengan direktori saat ini, sementara beberapa API memerlukan jalur yang sepenuhnya memenuhi syarat. Nama file bersifat relatif terhadap direktori saat ini jika tidak dimulai dengan salah satu dari berikut ini:
- Nama UNC dalam format apa pun, yang selalu dimulai dengan dua karakter garis miring terbalik ("\"). Untuk informasi lebih lanjut, lihat bagian selanjutnya.
- Penunjuk disk dengan garis miring terbalik, misalnya "C: \" atau "d: \".
- Satu garis miring terbalik, misalnya, "\ direktori" atau "\ file.txt". Ini juga disebut sebagai jalur absolut.
Jika nama file dimulai dengan hanya penunjuk disk tetapi tidak dengan garis miring terbalik setelah titik dua, itu diartikan sebagai jalur relatif ke direktori saat ini pada drive dengan huruf yang ditentukan. Perhatikan bahwa direktori saat ini mungkin atau mungkin bukan direktori root tergantung pada apa yang disetel selama operasi "direktori perubahan" terbaru pada disk tersebut. 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 di subdirektori ke direktori saat ini di drive C.
[...]
Pertanyaan lama, tapi satu jawaban lagi yang bisa diterapkan. 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
}
GetFullPath
mengakses sistem file dan dapat memberikan sejumlah kemungkinan pengecualian. Lihat jawaban saya ( stackoverflow.com/a/35046453/704808 ) untuk alternatif yang masih memastikan jalur lengkap.
Membangun jawaban weir : ini tidak menampilkan 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;
string 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;
if (pathRoot[0] != '\\' || pathRoot[1] != '\\')
return true; // Rooted and not a UNC path
return pathRoot.Trim('\\').IndexOf('\\') != -1; // A UNC server name without a share name (e.g "\\NAME" or "\\NAME\") is invalid
}
Perhatikan bahwa ini mengembalikan hasil yang berbeda pada Windows dan Linux, misalnya "/ path" adalah absolut di Linux, tetapi tidak di 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);
TryIsFullPath(@"\\is_this_a_dir_or_a_hostname\", false, !isWindows);
TryIsFullPath(@"\\is_this_a_dir_or_a_hostname\\", false, !isWindows);
}
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);
}
}
Untuk memeriksa apakah jalur sepenuhnya memenuhi syarat (MSDN) :
public static bool IsPathFullyQualified(string path)
{
var root = Path.GetPathRoot(path);
return root.StartsWith(@"\\") || root.EndsWith(@"\");
}
Ini sedikit lebih sederhana daripada yang telah diusulkan, dan masih mengembalikan false untuk jalur relatif-drive seperti C:foo
. Logikanya didasarkan langsung pada definisi MSDN "berkualifikasi penuh", dan saya belum menemukan contoh perilaku yang tidak semestinya.
Namun yang menarik, .NET Core 2.1 tampaknya memiliki metode baru Path.IsPathFullyQualified
yang menggunakan metode internal PathInternal.IsPartiallyQualified
(lokasi tautan akurat pada 2018-04-17).
Untuk anak cucu dan penahanan diri 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]));
}
Ini adalah solusi yang saya gunakan
public static bool IsFullPath(string path)
{
try
{
return Path.GetFullPath(path) == path;
}
catch
{
return false;
}
}
Ini 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
C:\foo\..\foo
atauC:\foo\.\.\.
Panggil fungsi berikut:
Path.IsPathFullyQualified(@"c:\foo")
Dok MSDN: Metode Path.IsPathFullyQualified
Kutipan berguna dari dokumen MSDN berikut:
Metode ini menangani jalur yang menggunakan pemisah direktori alternatif. Merupakan kesalahan yang sering terjadi untuk menganggap bahwa jalur yang di-root ( IsPathRooted (String) ) tidak relatif. Misalnya, "C: a" adalah drive relatif, artinya, diselesaikan terhadap direktori saat ini untuk C: (berakar, tetapi relatif). "C: \ a" di-root dan tidak relatif, artinya, direktori saat ini tidak digunakan untuk mengubah jalur.
Saya tidak begitu yakin apa yang Anda maksud dengan jalur lengkap (meskipun dengan asumsi dari contoh yang Anda maksud non-relatif dari root dan seterusnya), nah, Anda dapat menggunakan kelas Path untuk membantu Anda dalam bekerja dengan jalur sistem file fisik, yang harus mencakup Anda untuk sebagian besar kemungkinan.