पूर्ण पथ दिए जाने पर जाँच करें


104

क्या कोई विधि है कि क्या पूर्ण पथ पूर्ण है? अभी यह कर im:

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

लेकिन इसकी जाँच के लिए अधिक सुरुचिपूर्ण तरीका होना चाहिए?

जवाबों:


141

प्रयोग करके देखें System.IO.Path.IsPathRooted? यह trueनिरपेक्ष रास्तों के लिए भी लौटता है ।

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"

14
कैसे दूसरा उदाहरण निरपेक्ष पथ हो सकता है?
om471987

4
दूसरा मार्ग निरपेक्ष नहीं है, हालांकि यह जड़ है। प्रमुख स्लैश सिस्टम की जड़ को इंगित करता है।
डेटायलर

3
@SmirkinGherkin तो जड़ और निरपेक्ष मार्ग में क्या अंतर है?
जेसन एक्सलसन

1
एक विकल्प के लिए मेरा उत्तर ( stackoverflow.com/a/35046453/704808 ) देखें जो कि फायदे को बनाए रखते हुए एक पूर्ण मार्ग सुनिश्चित करता है IsPathRooted: फ़ाइल सिस्टम तक पहुँचने से बचना या अमान्य इनपुट के लिए अपवादों को फेंकना।
वार

1
@daniel, IIRC यह दिखाने के लिए शामिल किया गया था कि पथ का उपयोग करने के लिए एक वैध मार्ग होने की आवश्यकता नहीं है IsPathRooted, यह निश्चित रूप से कुछ भी महत्वपूर्ण नहीं है। GetFullPathलाइन तो शामिल किया गया था कि पथ मूल्यांकन किया जा रहा मनाया जा सकता है
detaylor

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

उपरोक्त स्थिति:

  • फ़ाइल सिस्टम अनुमतियों की आवश्यकता नहीं है
  • falseअधिकांश मामलों में रिटर्न जहां का प्रारूप pathअमान्य है (अपवाद फेंकने के बजाय)
  • रिटर्न trueकेवल तभी pathमात्रा भी शामिल है

ओपी के सामने आने वाले परिदृश्यों में, इसलिए यह पहले के उत्तर की स्थितियों से अधिक उपयुक्त हो सकता है। उपरोक्त स्थिति के विपरीत:

  • path == System.IO.Path.GetFullPath(path)falseइन परिदृश्यों में लौटने के बजाय अपवाद फेंकता है:
    • कॉलर के पास आवश्यक अनुमतियाँ नहीं हैं
    • सिस्टम निरपेक्ष पथ प्राप्त नहीं कर सका
    • पथ में एक बृहदान्त्र (":") होता है जो वॉल्यूम पहचानकर्ता का हिस्सा नहीं होता है
    • निर्दिष्ट पथ, फ़ाइल नाम या सिस्टम-निर्धारित अधिकतम लंबाई से अधिक है
  • System.IO.Path.IsPathRooted(path)रिटर्न trueयदि pathएकल निर्देशिका विभाजक के साथ शुरू होता है।

अंत में, यहाँ एक विधि है जो उपरोक्त स्थिति को लपेटता है और शेष संभावित अपवादों को भी प्रभावित करता है:

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 ने एक अच्छी टिप्पणी और वैकल्पिक उत्तर दिया , जैसे C:और रास्ते के उत्सुक मामले को संबोधित करते हुए C:dir। यह तय करने में मदद के लिए कि आप ऐसे रास्तों को कैसे संभालना चाहते हैं, आप MSDN -> विंडोज डेस्कटॉप अनुप्रयोगों के लिए गहरा गोता लगाना चाहते हैं -> विकसित -> डेस्कटॉप तकनीक -> डेटा एक्सेस और स्टोरेज -> स्थानीय फ़ाइल सिस्टम - -> फ़ाइल प्रबंधन -> फ़ाइल प्रबंधन के बारे में -> फाइलें बनाना, हटाना और बनाए रखना -> नामकरण फ़ाइलें, पथ और नाम स्थान -> पूरी तरह से योग्य बनाम सापेक्ष पथ

विंडोज एपीआई कार्यों के लिए जो फाइलों में हेरफेर करते हैं, फ़ाइल नाम अक्सर वर्तमान निर्देशिका के सापेक्ष हो सकते हैं, जबकि कुछ एपीआई को पूरी तरह से योग्य पथ की आवश्यकता होती है। एक फ़ाइल नाम वर्तमान निर्देशिका के सापेक्ष है यदि यह निम्न में से एक के साथ शुरू नहीं होता है:

  • किसी भी प्रारूप का एक UNC नाम, जो हमेशा दो बैकस्लैश अक्षरों ("\") से शुरू होता है। अधिक जानकारी के लिए, अगला भाग देखें।
  • बैकस्लैश के साथ एक डिस्क डिज़ाइनर, उदाहरण के लिए "C: \" या "d: \"।
  • एक बैकस्लैश, उदाहरण के लिए, "\ डायरेक्टरी" या "\ file.txt"। इसे निरपेक्ष पथ के रूप में भी जाना जाता है।

यदि फ़ाइल का नाम केवल एक डिस्क डिज़ाइनर के साथ शुरू होता है, लेकिन कोलन के बाद बैकस्लैश नहीं है, तो यह निर्दिष्ट पत्र के साथ ड्राइव पर वर्तमान निर्देशिका के सापेक्ष पथ के रूप में व्याख्या की गई है। ध्यान दें कि वर्तमान डिस्क उस डिस्क पर सबसे हाल ही में "परिवर्तन निर्देशिका" ऑपरेशन के दौरान सेट की गई पर निर्भर करती है या नहीं हो सकती है। इस प्रारूप के उदाहरण इस प्रकार हैं:

  • "C: tmp.txt" ड्राइव C पर वर्तमान निर्देशिका में "tmp.txt" नामक फ़ाइल को संदर्भित करता है।
  • "C: tempdir \ tmp.txt" ड्राइव C पर वर्तमान निर्देशिका में एक उपनिर्देशिका में एक फ़ाइल को संदर्भित करता है।

[...]


3
मुझे यह पसंद है कि यह अमान्य रास्तों के लिए नहीं फेंकता है, लेकिन यह "C:" और "C: dir" जैसे रास्तों के लिए सही है, जिन्हें GetFullPath द्वारा वर्तमान निर्देशिका का उपयोग करके हल किया जाता है (इसलिए वे पूर्ण नहीं हैं)। एक जवाब प्रकाशित किया जो इन के लिए गलत है।
EM0

@ EM0 - धन्यवाद! आपने अभी मुझे कुछ सिखाया है। :)
वार

15

प्रयत्न

System.IO.Path.IsPathRooted(template)

UNC पथों के साथ-साथ स्थानीय लोगों के लिए भी काम करता है।

उदाहरण के लिए

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

13

पुराना सवाल है, लेकिन एक और लागू जवाब। यदि आपको यह सुनिश्चित करने की आवश्यकता है कि वॉल्यूम एक स्थानीय पथ में शामिल है, तो आप System.IO.Path.GetFullPath () का उपयोग कर सकते हैं:

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
}

3
यह वही था जो मुझे चाहिए था, और मूल प्रश्न के करीब लगता है क्योंकि IsPathRooted 'सापेक्ष पथों के लिए सही है (जरूरी नहीं कि पूर्ण पथ)
बिटकोडर

GetFullPathफ़ाइल सिस्टम तक पहुँचता है और कई संभावित अपवादों को फेंक सकता है। एक विकल्प के लिए मेरा जवाब ( stackoverflow.com/a/35046453/704808 ) देखें जो अभी भी एक पूर्ण पथ सुनिश्चित करता है।
बांध

11

वियर के उत्तर पर बिल्डिंग : यह अमान्य रास्तों के लिए नहीं फेंकता है, बल्कि false"C:", "C: dirname" और "\ 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
}

ध्यान दें कि यह विंडोज और लिनक्स पर अलग-अलग परिणाम देता है, उदाहरण के लिए "/ पथ" लिनक्स पर निरपेक्ष है, लेकिन विंडोज पर नहीं।

अध्याय परीक्षा:

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

अच्छी चीज़। मैं नोटिस किया था कि msdn.microsoft.com/en-us/library/windows/desktop/... कहा गया है कि विंडोज पर एक रास्ता है नहीं रिश्तेदार अगर यह साथ शुरू होता है 'एक एकल बैकस्लैश, उदाहरण के लिए, "\ निर्देशिका" या "\ फ़ाइल ।टेक्स्ट"। इसे एक पूर्ण पथ के रूप में भी जाना जाता है। '
बांध

1
अच्छी बात! लगता है जैसे मेरी शब्दावली बंद थी। जब मैंने कहा "निरपेक्ष पथ" मैं वास्तव में सोच रहा था कि एमएस एक "पूर्ण पथ" को क्या कहता है। मैंने नाम बदल दिया है और इसके लिए एक परीक्षण मामला जोड़ा है।
EM0

1
इस उत्तर के लिए धन्यवाद, इसने मेरी बहुत मदद की। हालाँकि, ध्यान दें कि UNC पथ जैसे कि \\ server \ के लिए, यह पद्धति सही है, लेकिन यह अपवाद को छोड़ देगा यदि आप निर्देशिका (एक्सट्रैक्ट) (पथ) (System.ArgumentException) को कॉल करते हैं: 'UNC पथ फॉर्म का होना चाहिए \\ सर्वर \ शेयर।))
कार्ल

2
लोगों को अभी भी इसका उपयोग करते हुए और नए किनारे के मामलों को देखकर अच्छा लगा @Carl उस के लिए कोड और परीक्षण अपडेट करें!
EM0

6

यह जाँचने के लिए कि कोई पथ पूरी तरह से योग्य है (MSDN) :

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

यह पहले से प्रस्तावित किए जाने की तुलना में थोड़ा सरल है, और यह अभी भी ड्राइव-रिलेटिव पाथ के लिए गलत है C:foo। इसका तर्क सीधे "पूर्ण रूप से योग्य" की MSDN परिभाषा पर आधारित है, और मुझे ऐसा कोई उदाहरण नहीं मिला है जिस पर यह गलत व्यवहार करता हो।


हालांकि दिलचस्प बात यह है कि .NET कोर 2.1 में एक नया तरीका है Path.IsPathFullyQualifiedजो एक आंतरिक विधि PathInternal.IsPartiallyQualified(2018-04-17 के अनुसार लिंक स्थान सटीक) का उपयोग करता है।

इस पद के पश्चात और बेहतर स्व-नियंत्रण के लिए, यहाँ संदर्भ के लिए बाद का कार्यान्वयन है:

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

4

यह मेरे द्वारा उपयोग किया जाने वाला समाधान है

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

यह निम्नलिखित तरीके से काम करता है:

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याC:\foo\.\.\.
sergtk

1

निम्नलिखित फ़ंक्शन को कॉल करें:

Path.IsPathFullyQualified(@"c:\foo")

MSDN doc: Path.IsPathFullyQualified विधि

MSDN डॉक से उपयोगी उद्धरण इस प्रकार है:

यह विधि उन पथों को संभालती है जो वैकल्पिक निर्देशिका विभाजक का उपयोग करते हैं। यह मान लेना एक लगातार गलती है कि रूट किए गए रास्ते ( IsPathRooted (स्ट्रिंग) ) सापेक्ष नहीं हैं। उदाहरण के लिए, "C: a" ड्राइव रिलेटिव है, अर्थात यह C: (निहित, लेकिन रिलेटिव) के लिए वर्तमान डायरेक्टरी के विरूद्ध हल होता है। "C: \" एक निहित है और सापेक्ष नहीं है, अर्थात, मार्ग को संशोधित करने के लिए वर्तमान निर्देशिका का उपयोग नहीं किया जाता है।


0

मुझे वास्तव में यकीन नहीं है कि आपको पूर्ण पथ से क्या मतलब है (हालांकि उदाहरण से आप रूट से गैर-रिश्तेदार का मतलब मानते हैं), ठीक है, आप भौतिक फाइल सिस्टम पथ के साथ काम करने में सहायता करने के लिए पथ वर्ग का उपयोग कर सकते हैं , जिसे कवर करना चाहिए आप अधिकांश घटनाओं के लिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.