c# - जांचने का बेहतर तरीका है कि क्या पथ फ़ाइल या निर्देशिका है?


मैं निर्देशिकाओं और फ़ाइलों के एक TreeView प्रसंस्करण कर रहा हूँ एक उपयोगकर्ता या तो फाइल या निर्देशिका का चयन कर सकता है और उसके साथ कुछ कर सकता है इसके लिए मुझे एक ऐसा तरीका चाहिए जो उपयोगकर्ता के चयन के आधार पर अलग-अलग कार्य करता है।

फिलहाल मैं यह तय करने के लिए कुछ कर रहा हूं कि पथ एक फ़ाइल या निर्देशिका है या नहीं:

bool bIsFile = false;
bool bIsDirectory = false;

try
{
    string[] subfolders = Directory.GetDirectories(strFilePath);

    bIsDirectory = true;
    bIsFile = false;
}
catch(System.IO.IOException)
{
    bIsFolder = false;
    bIsFile = true;
}

मैं यह महसूस करने में मदद नहीं कर सकता कि ऐसा करने का एक बेहतर तरीका है! मैं इसे संभाल करने के लिए एक मानक .NET विधि खोजने की उम्मीद कर रहा था, लेकिन मैं ऐसा करने में सक्षम नहीं था। क्या ऐसी विधि मौजूद है, और यदि नहीं, तो यह निर्धारित करने के लिए सबसे सीधा अर्थ क्या है कि कोई पथ फ़ाइल या निर्देशिका है या नहीं?


Answers



कैसे बताओ कि पथ फ़ाइल या निर्देशिका है :

// get the file attributes for file or directory
FileAttributes attr = File.GetAttributes(@"c:\Temp");

//detect whether its a directory or file
if ((attr & FileAttributes.Directory) == FileAttributes.Directory)
    MessageBox.Show("Its a directory");
else
    MessageBox.Show("Its a file");

.NET 4.0+ के लिए अद्यतन

नीचे दिए गए टिप्पणियों के अनुसार, यदि आप .NET 4.0 या बाद में हैं (और अधिकतम प्रदर्शन महत्वपूर्ण नहीं है) तो आप कोड को क्लीनर तरीके से लिख सकते हैं:

// get the file attributes for file or directory
FileAttributes attr = File.GetAttributes(@"c:\Temp");

if (attr.HasFlag(FileAttributes.Directory))
    MessageBox.Show("Its a directory");
else
    MessageBox.Show("Its a file");



कैसे इन के उपयोग के बारे में?

File.Exists();
Directory.Exists();



केवल एक ही पंक्ति के साथ आप प्राप्त कर सकते हैं यदि कोई पथ निर्देशिका या फ़ाइल है:

File.GetAttributes(data.Path).HasFlag(FileAttributes.Directory)



सबसे सटीक दृष्टिकोण shlwapi.dll से कुछ इंटरॉप कोड का उपयोग करने जा रहा है

[DllImport(SHLWAPI, CharSet = CharSet.Unicode)]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
[ResourceExposure(ResourceScope.None)]
internal static extern bool PathIsDirectory([MarshalAsAttribute(UnmanagedType.LPWStr), In] string pszPath);

आप इसे इस प्रकार कहते हैं:

#region IsDirectory
/// <summary>
/// Verifies that a path is a valid directory.
/// </summary>
/// <param name="path">The path to verify.</param>
/// <returns><see langword="true"/> if the path is a valid directory; 
/// otherwise, <see langword="false"/>.</returns>
/// <exception cref="T:System.ArgumentNullException">
/// <para><paramref name="path"/> is <see langword="null"/>.</para>
/// </exception>
/// <exception cref="T:System.ArgumentException">
/// <para><paramref name="path"/> is <see cref="F:System.String.Empty">String.Empty</see>.</para>
/// </exception>
public static bool IsDirectory(string path)
{
    return PathIsDirectory(path);
}



डायरेक्टरी के विकल्प के रूप में। एक्सिस (), आप फ़ाइल या निर्देशिका की विशेषताओं को प्राप्त करने के लिए File.GetAttributes () विधि का उपयोग कर सकते हैं, ताकि आप इस तरह एक सहायक विधि बना सकें:

private static bool IsDirectory(string path)
{
    System.IO.FileAttributes fa = System.IO.File.GetAttributes(path);
    bool isDirectory = false;
    if ((fa & FileAttributes.Directory) != 0)
    {
        isDirectory = true;
    }
    return isDirectory;
}

आप आइटम को अतिरिक्त मेटाडेटा रखने वाले नियंत्रण को लोकप्रिय करते समय ट्रीविय कंट्रोल के टैग प्रॉपर्टी में ऑब्जेक्ट को जोड़ने पर विचार कर सकते हैं। उदाहरण के लिए, आप फ़ाइलों के लिए एक फाइल इन्फॉउऑब्स ऑब्जेक्ट जोड़ सकते हैं और डायरेक्टरी के लिए एक निर्देशिकाइन्फ़ो ऑब्जेक्ट कर सकते हैं और फिर आइटम पर क्लिक करते समय उस डेटा को प्राप्त करने के लिए अतिरिक्त सिस्टम कॉल्स को सहेजने के लिए टैग प्रॉपर्टी में आइटम प्रकार के लिए परीक्षण करें।




अस्तित्व और गुण गुणों के व्यवहार को देखते हुए यह सबसे अच्छा था:

using System.IO;

public static class FileSystemInfoExtensions
{
    /// <summary>
    /// Checks whether a FileInfo or DirectoryInfo object is a directory, or intended to be a directory.
    /// </summary>
    /// <param name="fileSystemInfo"></param>
    /// <returns></returns>
    public static bool IsDirectory(this FileSystemInfo fileSystemInfo)
    {
        if (fileSystemInfo == null)
        {
            return false;
        }

        if ((int)fileSystemInfo.Attributes != -1)
        {
            // if attributes are initialized check the directory flag
            return fileSystemInfo.Attributes.HasFlag(FileAttributes.Directory);
        }

        // If we get here the file probably doesn't exist yet.  The best we can do is 
        // try to judge intent.  Because directories can have extensions and files
        // can lack them, we can't rely on filename.
        // 
        // We can reasonably assume that if the path doesn't exist yet and 
        // FileSystemInfo is a DirectoryInfo, a directory is intended.  FileInfo can 
        // make a directory, but it would be a bizarre code path.

        return fileSystemInfo is DirectoryInfo;
    }
}

यहां बताया गया है कि यह कैसे परीक्षण करता है:

    [TestMethod]
    public void IsDirectoryTest()
    {
        // non-existing file, FileAttributes not conclusive, rely on type of FileSystemInfo
        const string nonExistentFile = @"C:\TotallyFakeFile.exe";

        var nonExistentFileDirectoryInfo = new DirectoryInfo(nonExistentFile);
        Assert.IsTrue(nonExistentFileDirectoryInfo.IsDirectory());

        var nonExistentFileFileInfo = new FileInfo(nonExistentFile);
        Assert.IsFalse(nonExistentFileFileInfo.IsDirectory());

        // non-existing directory, FileAttributes not conclusive, rely on type of FileSystemInfo
        const string nonExistentDirectory = @"C:\FakeDirectory";

        var nonExistentDirectoryInfo = new DirectoryInfo(nonExistentDirectory);
        Assert.IsTrue(nonExistentDirectoryInfo.IsDirectory());

        var nonExistentFileInfo = new FileInfo(nonExistentDirectory);
        Assert.IsFalse(nonExistentFileInfo.IsDirectory());

        // Existing, rely on FileAttributes
        const string existingDirectory = @"C:\Windows";

        var existingDirectoryInfo = new DirectoryInfo(existingDirectory);
        Assert.IsTrue(existingDirectoryInfo.IsDirectory());

        var existingDirectoryFileInfo = new FileInfo(existingDirectory);
        Assert.IsTrue(existingDirectoryFileInfo.IsDirectory());

        // Existing, rely on FileAttributes
        const string existingFile = @"C:\Windows\notepad.exe";

        var existingFileDirectoryInfo = new DirectoryInfo(existingFile);
        Assert.IsFalse(existingFileDirectoryInfo.IsDirectory());

        var existingFileFileInfo = new FileInfo(existingFile);
        Assert.IsFalse(existingFileFileInfo.IsDirectory());
    }



ये मेरा:

    bool IsPathDirectory(string path)
    {
        if (path == null) throw new ArgumentNullException("path");
        path = path.Trim();

        if (Directory.Exists(path)) 
            return true;

        if (File.Exists(path)) 
            return false;

        // neither file nor directory exists. guess intention

        // if has trailing slash then it's a directory
        if (new[] {"\\", "/"}.Any(x => path.EndsWith(x)))
            return true; // ends with slash

        // if has extension then its a file; directory otherwise
        return string.IsNullOrWhiteSpace(Path.GetExtension(path));
    }

यह दूसरों के उत्तर के समान है, लेकिन ठीक उसी तरह नहीं।




मैं इस पर एक ऐसी समस्या का सामना करते समय आया था, सिवाय मुझे यह जांचने की आवश्यकता थी कि कोई पथ फ़ाइल या फ़ोल्डर के लिए है, जब वह फ़ाइल या फ़ोल्डर वास्तव में मौजूद नहीं हो । ऊपर दिए गए उत्तर पर कुछ टिप्पणियां थीं, जो उल्लेख किया है कि वे इस परिदृश्य के लिए काम नहीं करेंगे। मुझे एक समाधान मिला (मैं VB.NET का उपयोग करता हूं, लेकिन यदि आप की आवश्यकता है तो आप कनवर्ट कर सकते हैं) जो मेरे लिए अच्छी तरह से काम करते हैं:

Dim path As String = "myFakeFolder\ThisDoesNotExist\"
Dim bIsFolder As Boolean = (IO.Path.GetExtension(path) = "")
'returns True

Dim path As String = "myFakeFolder\ThisDoesNotExist\File.jpg"
Dim bIsFolder As Boolean = (IO.Path.GetExtension(path) = "")
'returns False

उम्मीद है कि यह किसी के लिए सहायक हो सकता है!




बहुत देर बाद खेल में मुझे पता है, लेकिन सोचा कि मैं वैसे भी इसे साझा करेंगे। यदि आप केवल पथ के रूप में पथ के साथ काम कर रहे हैं, यह पता लगाने के लिए पाई के रूप में आसान है:

private bool IsFolder(string ThePath)
{
    string BS = Path.DirectorySeparatorChar.ToString();
    return Path.GetDirectoryName(ThePath) == ThePath.TrimEnd(BS.ToCharArray());
}

उदाहरण के लिए: ThePath == "C:\SomeFolder\File1.txt" अंत में यह होगा:

return "C:\SomeFolder" == "C:\SomeFolder\File1.txt" (FALSE)

एक अन्य उदाहरण: ThePath == "C:\SomeFolder\" समाप्त होने वाला होगा:

return "C:\SomeFolder" == "C:\SomeFolder" (TRUE)

और ये पीछे वाले बैकस्लैश के बिना भी काम करेगा: ThePath == "C:\SomeFolder" समाप्त हो जाएगा:

return "C:\SomeFolder" == "C:\SomeFolder" (TRUE)

ध्यान रखें कि यह केवल पथ के साथ काम करता है, और पथ और "भौतिक डिस्क" के बीच संबंध नहीं होता है ... इसलिए यह आपको नहीं बता सकता है कि पथ / फ़ाइल मौजूद है या उस जैसी कुछ भी है, लेकिन यह निश्चित है आपको बता सकता है कि पथ एक फ़ोल्डर या फ़ाइल है ...




यहां हम जो उपयोग करते हैं वह है:

using System;

using System.IO;

namespace crmachine.CommonClasses
{

  public static class CRMPath
  {

    public static bool IsDirectory(string path)
    {
      if (path == null)
      {
        throw new ArgumentNullException("path");
      }

      string reason;
      if (!IsValidPathString(path, out reason))
      {
        throw new ArgumentException(reason);
      }

      if (!(Directory.Exists(path) || File.Exists(path)))
      {
        throw new InvalidOperationException(string.Format("Could not find a part of the path '{0}'",path));
      }

      return (new System.IO.FileInfo(path).Attributes & FileAttributes.Directory) == FileAttributes.Directory;
    } 

    public static bool IsValidPathString(string pathStringToTest, out string reasonForError)
    {
      reasonForError = "";
      if (string.IsNullOrWhiteSpace(pathStringToTest))
      {
        reasonForError = "Path is Null or Whitespace.";
        return false;
      }
      if (pathStringToTest.Length > CRMConst.MAXPATH) // MAXPATH == 260
      {
        reasonForError = "Length of path exceeds MAXPATH.";
        return false;
      }
      if (PathContainsInvalidCharacters(pathStringToTest))
      {
        reasonForError = "Path contains invalid path characters.";
        return false;
      }
      if (pathStringToTest == ":")
      {
        reasonForError = "Path consists of only a volume designator.";
        return false;
      }
      if (pathStringToTest[0] == ':')
      {
        reasonForError = "Path begins with a volume designator.";
        return false;
      }

      if (pathStringToTest.Contains(":") && pathStringToTest.IndexOf(':') != 1)
      {
        reasonForError = "Path contains a volume designator that is not part of a drive label.";
        return false;
      }
      return true;
    }

    public static bool PathContainsInvalidCharacters(string path)
    {
      if (path == null)
      {
        throw new ArgumentNullException("path");
      }

      bool containedInvalidCharacters = false;

      for (int i = 0; i < path.Length; i++)
      {
        int n = path[i];
        if (
            (n == 0x22) || // "
            (n == 0x3c) || // <
            (n == 0x3e) || // >
            (n == 0x7c) || // |
            (n  < 0x20)    // the control characters
          )
        {
          containedInvalidCharacters = true;
        }
      }

      return containedInvalidCharacters;
    }


    public static bool FilenameContainsInvalidCharacters(string filename)
    {
      if (filename == null)
      {
        throw new ArgumentNullException("filename");
      }

      bool containedInvalidCharacters = false;

      for (int i = 0; i < filename.Length; i++)
      {
        int n = filename[i];
        if (
            (n == 0x22) || // "
            (n == 0x3c) || // <
            (n == 0x3e) || // >
            (n == 0x7c) || // |
            (n == 0x3a) || // : 
            (n == 0x2a) || // * 
            (n == 0x3f) || // ? 
            (n == 0x5c) || // \ 
            (n == 0x2f) || // /
            (n  < 0x20)    // the control characters
          )
        {
          containedInvalidCharacters = true;
        }
      }

      return containedInvalidCharacters;
    }

  }

}



मैं निम्नलिखित का उपयोग करता हूं, यह एक्सटेंशन की जांच भी करता है जिसका मतलब है कि यह परीक्षण के लिए इस्तेमाल किया जा सकता है यदि पथ प्रदान किया गया एक फाइल है, लेकिन ऐसा फ़ाइल जो मौजूद नहीं है

private static bool isDirectory(string path)
{
    bool result = true;
    System.IO.FileInfo fileTest = new System.IO.FileInfo(path);
    if (fileTest.Exists == true)
    {
        result = false;
    }
    else
    {
        if (fileTest.Extension != "")
        {
            result = false;
        }
    }
    return result;
}



यदि आप "छुपा" और "सिस्टम" चिह्नित हैं, उन निर्देशिकाओं को ढूंढना चाहते हैं, तो कोशिश करें (.NET V4 की आवश्यकता है):

FileAttributes fa = File.GetAttributes(path);
if(fa.HasFlag(FileAttributes.Directory)) 



using System;
using System.IO;
namespace FileOrDirectory
{
     class Program
     {
          public static string FileOrDirectory(string path)
          {
               if (File.Exists(path))
                    return "File";
               if (Directory.Exists(path))
                    return "Directory";
               return "Path Not Exists";
          }
          static void Main()
          {
               Console.WriteLine("Enter The Path:");
               string path = Console.ReadLine();
               Console.WriteLine(FileOrDirectory(path));
          }
     }
}



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

if (!Directory.Exists(@"C:\folderName")) return;



इस पोस्ट पर चयनित उत्तर का इस्तेमाल करते हुए, मैंने टिप्पणियों को देखा और @ प्रोफेगर, @ एन्थनी और @ क्विन विल्सन को अपनी जानकारी बिट्स के लिए आश्वस्त किया जो मुझे इस सुधरे हुए उत्तर के लिए प्रेरित करते हैं जो मैंने लिखा और परीक्षण किया था:

    /// <summary>
    /// Returns true if the path is a dir, false if it's a file and null if it's neither or doesn't exist.
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    public static bool? IsDirFile(this string path)
    {
        bool? result = null;

        if(Directory.Exists(path) || File.Exists(path))
        {
            // get the file attributes for file or directory
            var fileAttr = File.GetAttributes(path);

            if (fileAttr.HasFlag(FileAttributes.Directory))
                result = true;
            else
                result = false;
        }

        return result;
    }



अन्य उत्तरों के सुझावों के संयोजन के बाद, मुझे एहसास हुआ कि मैं रॉनी ओवरबी के जवाब के बारे में एक ही बात के बारे में आया हूं। कुछ बातों के बारे में सोचने के लिए यहां कुछ परीक्षण दिए गए हैं:

  1. फ़ोल्डर में "एक्सटेंशन" हो सकते हैं: C:\Temp\folder_with.dot
  2. फ़ाइलें एक निर्देशिका विभाजक (स्लैश) के साथ समाप्त नहीं हो सकतीं
  3. तकनीकी रूप से दो निर्देशिका विभाजक हैं जो प्लेटफ़ॉर्म विशिष्ट हैं - अर्थात या स्लेश नहीं हो सकते हैं ( Path.DirectorySeparatorChar और Path.AltDirectorySeparatorChar )

टेस्ट (लिनक्पाड)

var paths = new[] {
    // exists
    @"C:\Temp\dir_test\folder_is_a_dir",
    @"C:\Temp\dir_test\is_a_dir_trailing_slash\",
    @"C:\Temp\dir_test\existing_folder_with.ext",
    @"C:\Temp\dir_test\file_thats_not_a_dir",
    @"C:\Temp\dir_test\notadir.txt",
    // doesn't exist
    @"C:\Temp\dir_test\dne_folder_is_a_dir",
    @"C:\Temp\dir_test\dne_folder_trailing_slash\",
    @"C:\Temp\dir_test\non_existing_folder_with.ext",
    @"C:\Temp\dir_test\dne_file_thats_not_a_dir",
    @"C:\Temp\dir_test\dne_notadir.txt",        
};

foreach(var path in paths) {
    IsFolder(path/*, false*/).Dump(path);
}

परिणाम

C:\Temp\dir_test\folder_is_a_dir
  True 
C:\Temp\dir_test\is_a_dir_trailing_slash\
  True 
C:\Temp\dir_test\existing_folder_with.ext
  True 
C:\Temp\dir_test\file_thats_not_a_dir
  False 
C:\Temp\dir_test\notadir.txt
  False 
C:\Temp\dir_test\dne_folder_is_a_dir
  True 
C:\Temp\dir_test\dne_folder_trailing_slash\
  True 
C:\Temp\dir_test\non_existing_folder_with.ext
  False (this is the weird one)
C:\Temp\dir_test\dne_file_thats_not_a_dir
  True 
C:\Temp\dir_test\dne_notadir.txt
  False 

तरीका

/// <summary>
/// Whether the <paramref name="path"/> is a folder (existing or not); 
/// optionally assume that if it doesn't "look like" a file then it's a directory.
/// </summary>
/// <param name="path">Path to check</param>
/// <param name="assumeDneLookAlike">If the <paramref name="path"/> doesn't exist, does it at least look like a directory name?  As in, it doesn't look like a file.</param>
/// <returns><c>True</c> if a folder/directory, <c>false</c> if not.</returns>
public static bool IsFolder(string path, bool assumeDneLookAlike = true)
{
    // https://.com/questions/1395205/better-way-to-check-if-path-is-a-file-or-a-directory
    // turns out to be about the same as https://.com/a/19596821/1037948

    // check in order of verisimilitude

    // exists or ends with a directory separator -- files cannot end with directory separator, right?
    if (Directory.Exists(path)
        // use system values rather than assume slashes
        || path.EndsWith("" + Path.DirectorySeparatorChar)
        || path.EndsWith("" + Path.AltDirectorySeparatorChar))
        return true;

    // if we know for sure that it's an actual file...
    if (File.Exists(path))
        return false;

    // if it has an extension it should be a file, so vice versa
    // although technically directories can have extensions...
    if (!Path.HasExtension(path) && assumeDneLookAlike)
        return true;

    // only works for existing files, kinda redundant with `.Exists` above
    //if( File.GetAttributes(path).HasFlag(FileAttributes.Directory) ) ...; 

    // no idea -- could return an 'indeterminate' value (nullable bool)
    // or assume that if we don't know then it's not a folder
    return false;
}



क्या यह काम नहीं करेगा?

var isFile = Regex.IsMatch(path, @"\w{1,}\.\w{1,}$");



यह विशेषता प्राप्त करने के लिए DirectoryInfo का उपयोग कर रहा है

Dim newnode As TreeNode
Dim dirs As New DirectoryInfo(node.FullPath)
For Each dir As DirectoryInfo In dirs.GetDirectories()
    If dir.Attributes = FileAttributes.Directory Then

    Else

    End If
Next

यह काम करेगा यदि आप DirectoryInfo के माध्यम से एक TreeView बनाने या TreeView को पढ़ने की कोशिश कर रहे हैं








Links