Cách tốt hơn để kiểm tra xem Đường dẫn là Tệp hay Thư mục?


382

Tôi đang xử lý một TreeViewthư mục và tập tin. Người dùng có thể chọn một tệp hoặc một thư mục và sau đó làm một cái gì đó với nó. Điều này đòi hỏi tôi phải có một phương thức thực hiện các hành động khác nhau dựa trên lựa chọn của người dùng.

Hiện tại tôi đang làm một cái gì đó như thế này để xác định xem đường dẫn là tệp hoặc thư mục:

bool bIsFile = false;
bool bIsDirectory = false;

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

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

Tôi không thể giúp cảm thấy rằng có một cách tốt hơn để làm điều này! Tôi đã hy vọng tìm thấy một phương thức .NET tiêu chuẩn để xử lý việc này, nhưng tôi chưa thể làm được. Liệu một phương thức như vậy có tồn tại không, và nếu không, phương tiện đơn giản nhất để xác định xem một đường dẫn là một tệp hoặc thư mục?


8
Ai đó có thể chỉnh sửa tiêu đề câu hỏi để chỉ định tập tin / thư mục "hiện có" không? Tất cả các câu trả lời áp dụng cho một đường dẫn cho một tập tin / thư mục trên đĩa.
Jake Berger

1
@jberger vui lòng tham khảo câu trả lời của tôi dưới đây. Tôi tìm thấy một cách để thực hiện điều này cho các đường dẫn của tệp / thư mục có thể tồn tại hoặc không tồn tại.
15:51


Làm thế nào bạn có dân cư treeview này? Làm thế nào bạn có được con đường ra khỏi nó?
Random832

Câu trả lời:


595

Từ Cách nhận biết đường dẫn là tệp hoặc thư mục :

// 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");

Cập nhật cho .NET 4.0+

Theo các bình luận bên dưới, nếu bạn dùng .NET 4.0 trở lên (và hiệu suất tối đa không quan trọng), bạn có thể viết mã theo cách sạch hơn:

// 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");

8
+1 Đây là cách tiếp cận tốt hơn và nhanh hơn đáng kể so với giải pháp tôi đã đề xuất.
Andrew Hare

6
@ KeyMs92 Toán học bitwise của nó. Về cơ bản, attr là một số giá trị nhị phân với một bit có nghĩa là "đây là một thư mục". &Toán tử bit và toán tử sẽ trả về một giá trị nhị phân trong đó chỉ các bit được bật (1) trong cả hai toán hạng được bật. Trong trường hợp này, thực hiện một bitwise và thao tác ngược lại attrFileAttributes.Directorygiá trị sẽ trả về giá trị FileAttributes.Directorynếu bit thuộc tính tệp thư mục được bật. Xem en.wikipedia.org/wiki/Bitwise_operation để được giải thích rõ hơn.
Kyle Trauberman

6
@jberger Nếu đường dẫn không tồn tại thì nó mơ hồ cho dù C:\Temptham chiếu đến một thư mục được gọi Temphoặc một tệp được gọi Temp. Mã này có nghĩa là gì?
ta.speot.is

26
@Key: Sau .NET 4.0, attr.HasFlag(FileAttributes.Directory)có thể được sử dụng thay thế.
Şafak Gür

13
@ AfakGür: Đừng làm điều này trong một vòng lặp nhạy cảm về thời gian. attr.HasFlag () chậm như địa ngục và sử dụng Reflection cho mỗi cuộc gọi
springy76

247

Làm thế nào về việc sử dụng những?

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

43
Điều này cũng có lợi thế là không ném ngoại lệ vào một đường dẫn không hợp lệ, không giống như File.GetAttributes().
Deanna

Tôi sử dụng thư viện Đường dẫn dài từ BCL bcl.codeplex.com/ trong dự án của mình để không có cách nào để có được các thuộc tính tệp nhưng gọi Exist là một cách giải quyết tốt.
Puterdo Borato

4
@jberger Tôi hy vọng nó KHÔNG hoạt động đối với các đường dẫn đến các tệp / thư mục không tồn tại. File.Exists ("c: \\ temp \\ nonexistant.txt") sẽ trả về false, như vậy.
michaelkoss

12
Nếu bạn lo lắng về các tệp / thư mục không tồn tại, hãy thử điều này public static bool? IsDirectory(string path){ if (Directory.Exists(path)) return true; // is a directory else if (File.Exists(path)) return false; // is a file else return null; // is a nothing }
Dustin Townsend

1
Thông tin chi tiết về vấn đề này có tại msdn.microsoft.com/en-us/l Library / từ
Moji

20

Chỉ với dòng này bạn có thể nhận được nếu một đường dẫn là một thư mục hoặc một tệp:

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

4
Tâm trí bạn cần ít nhất .NET 4.0 cho việc này. Ngoài ra, điều này sẽ phát nổ nếu đường dẫn không phải là một đường dẫn hợp lệ.
nawfal

Sử dụng một đối tượng FileInfo để kiểm tra xem đường dẫn có tồn tại không: FileInfo pFinfo = new FileInfo (FList [0]); if (pFinfo.Exists) {if (File.GetAttribut (FList [0]). HasFlag (FileAttribut.Directory)) {}}. Cái này làm việc cho tôi
Michael Promotionson

Nếu bạn đã tạo một đối tượng FileInfo và đang sử dụng thuộc tính Exists của cá thể, tại sao không truy cập thuộc tính Thuộc tính của nó thay vì sử dụng phương thức File.GetAttribut () tĩnh?
điện

10

Đây là của tôi:

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

Nó tương tự như câu trả lời của người khác nhưng không hoàn toàn giống nhau.


3
Về mặt kỹ thuật bạn nên sử dụng Path.DirectorySeparatorCharPath.AltDirectorySeparatorChar
drzaus 2/2/2016

1
Ý tưởng này để đoán ý định là thú vị. IMHO tốt hơn để chia thành hai phương pháp. Phương thức Một thực hiện các bài kiểm tra Hiện sinh, trả về một boolean nullable. Nếu người gọi sau đó muốn phần "đoán", trên kết quả null từ One, sau đó gọi Phương thức hai, phần này sẽ đoán.
ToolmakerSteve

2
Tôi sẽ viết lại cái này để trả lại một tuple với việc nó có đoán được hay không.
Ronnie Overby

1
"Nếu có phần mở rộng thì đó là một tập tin" - điều này không đúng. Một tập tin không phải có phần mở rộng (ngay cả trong windows) và một thư mục có thể có "phần mở rộng". Ví dụ: đây có thể là một tệp hoặc một thư mục: "C: \ Thư mục mới.log"
bytedev

2
@bytedev Tôi biết điều đó, nhưng tại thời điểm đó trong hàm, mã đang đoán ý định. Thậm chí còn có một bình luận nói như vậy. Hầu hết các tập tin có một phần mở rộng. Hầu hết các thư mục không.
Ronnie Overby

7

Thay thế cho Directory.Exists (), bạn có thể sử dụng phương thức File.GetAttribut () để lấy các thuộc tính của tệp hoặc thư mục, do đó bạn có thể tạo phương thức trợ giúp như thế này:

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

Bạn cũng có thể xem xét việc thêm một đối tượng vào thuộc tính thẻ của điều khiển TreeView khi điền vào điều khiển có chứa siêu dữ liệu bổ sung cho mục đó. Chẳng hạn, bạn có thể thêm một đối tượng FileInfo cho các tệp và đối tượng DirectoryInfo cho các thư mục và sau đó kiểm tra loại mục trong thuộc tính thẻ để lưu thực hiện các cuộc gọi hệ thống bổ sung để lấy dữ liệu đó khi nhấp vào mục.


2
Làm thế nào khác với câu trả lời
Jake Berger

6
Thay vì khối logic khủng khiếp đó, hãy thửisDirectory = (fa & FileAttributes.Directory) != 0);
Màu xanh bất tử

5

Đây là điều tốt nhất tôi có thể đưa ra với hành vi của các thuộc tính Tồn tại và Thuộc tính:

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

Đây là cách nó kiểm tra:

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

5

Sau khi kết hợp các gợi ý từ các câu trả lời khác, tôi nhận ra rằng tôi đã nghĩ ra điều tương tự như câu trả lời của Ronnie Overby . Dưới đây là một số thử nghiệm để chỉ ra một số điều cần suy nghĩ:

  1. thư mục có thể có "phần mở rộng": C:\Temp\folder_with.dot
  2. tập tin không thể kết thúc bằng dấu phân cách thư mục (dấu gạch chéo)
  3. Về mặt kỹ thuật có hai dấu tách thư mục dành riêng cho nền tảng - tức là có thể hoặc không thể là dấu gạch chéo ( Path.DirectorySeparatorCharPath.AltDirectorySeparatorChar)

Các thử nghiệm (Linqpad)

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ác kết quả

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 

phương pháp

/// <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)
{
    // /programming/1395205/better-way-to-check-if-path-is-a-file-or-a-directory
    // turns out to be about the same as https://stackoverflow.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;
}

Path.DirectorySeparatorChar.ToString()thay vì chuỗi concat với ""?
Mã hóa

@GoneCoding có lẽ; tại thời điểm tôi đã làm việc với một loạt các thuộc tính nullable nên tôi có thói quen "concat với chuỗi rỗng" thay vì lo lắng về việc kiểm tra null. Bạn cũng có thể làm new String(Path.DirectorySeparatorChar, 1)như ToStringvậy, nếu bạn muốn được tối ưu hóa thực sự .
drzaus

4

Cách tiếp cận chính xác nhất sẽ là sử dụng một số mã interop từ 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);

Sau đó, bạn sẽ gọi nó như thế này:

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

31
Xấu xí. Tôi ghét interop để làm những nhiệm vụ đơn giản này. Và nó không phải là di động. và nó xấu xí Tôi đã nói rằng nó xấu? :)
Ignacio Soler Garcia

5
@SoMoS Nó có thể là "xấu xí" theo ý kiến ​​của bạn, nhưng nó vẫn là cách tiếp cận chính xác nhất. Vâng, đó không phải là một giải pháp di động nhưng đó không phải là những gì câu hỏi.
Scott Dorman

8
Bạn có ý nghĩa chính xác với chính xác? Nó cho kết quả tương tự như câu trả lời từ Quinn Wilson và yêu cầu interop phá vỡ tính di động. Đối với tôi nó chính xác như các giải pháp khác và có tác dụng phụ khác.
Ignacio Soler Garcia

7
Có API API để làm điều này. Sử dụng Interop không phải là cách để đi.
TomXP411

5
Có, điều này hoạt động, nhưng nó KHÔNG phải là giải pháp "chính xác nhất" - không hơn gì việc sử dụng .NET Framework hiện có. Thay vào đó, bạn lấy 6 dòng mã để thay thế những gì có thể được thực hiện trong một dòng bằng .NET Framework và tự khóa chỉ sử dụng Windows, trái ngược với việc mở khả năng chuyển cái này với Dự án Mono. Không bao giờ sử dụng Interop khi .NET Framework cung cấp một giải pháp thanh lịch hơn.
Nga

2

Đây là những gì chúng tôi sử dụng:

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

  }

}

2

Tôi đã gặp phải vấn đề này khi gặp phải một vấn đề tương tự, ngoại trừ tôi cần kiểm tra xem một đường dẫn dành cho một tệp hoặc thư mục khi tệp hoặc thư mục đó có thể không thực sự tồn tại . Có một vài bình luận về các câu trả lời ở trên đã đề cập rằng chúng sẽ không hoạt động cho kịch bản này. Tôi đã tìm thấy một giải pháp (tôi sử dụng VB.NET, nhưng bạn có thể chuyển đổi nếu bạn cần) có vẻ như hoạt động tốt với tôi:

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

Hy vọng điều này có thể hữu ích cho ai đó!


1
Bạn đã thử phương pháp Path.HasExtension chưa?
Jake Berger

Nếu nó không tồn tại, thì đó không phải là một tập tin hoặc một thư mục. Bất kỳ tên nào cũng có thể được tạo. Nếu bạn có ý định tạo ra nó, thì bạn nên biết những gì bạn đang tạo và nếu bạn không, thì tại sao bạn có thể cần thông tin này?
Random832

8
Một thư mục có thể được đặt tên test.txtvà một tệp có thể được đặt tên test- trong những trường hợp này, mã của bạn sẽ trả về kết quả không chính xác
Stephan Bauer

2
Có một phương thức .Exists trong các lớp System.IO.FIle và System.IO.Directory. đó là điều cần làm Thư mục có thể có phần mở rộng; Tôi thấy nó thường xuyên.
TomXP411

2

Tôi biết rất muộn trong trò chơi, nhưng tôi nghĩ dù sao tôi cũng sẽ chia sẻ điều này. Nếu bạn chỉ làm việc với các đường dẫn dưới dạng chuỗi, việc tìm ra điều này dễ như ăn bánh:

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

ví dụ: ThePath == "C:\SomeFolder\File1.txt"sẽ kết thúc như thế này:

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

Một ví dụ khác: ThePath == "C:\SomeFolder\"cuối cùng sẽ là thế này:

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

Và điều này cũng sẽ hoạt động mà không có dấu gạch chéo ngược: ThePath == "C:\SomeFolder"cuối cùng sẽ là thế này:

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

Hãy ghi nhớ ở đây rằng điều này chỉ hoạt động với chính các đường dẫn chứ không phải mối quan hệ giữa đường dẫn và "đĩa vật lý" ... vì vậy nó không thể cho bạn biết nếu đường dẫn / tệp tồn tại hoặc bất cứ điều gì tương tự, nhưng chắc chắn có thể cho bạn biết nếu đường dẫn là một thư mục hoặc một tập tin ...


2
Không hoạt động System.IO.FileSystemWatcherkể từ khi một thư mục bị xóa, nó sẽ gửi c:\my_directorydưới dạng một đối số giống như khi một phần mở rộng ít tập tin c:\my_directorybị xóa.
Ray Cheng

GetDirectoryName('C:\SomeFolder')trả lại 'C:\', vì vậy trường hợp cuối cùng của bạn không hoạt động. Điều này không phân biệt giữa các thư mục và tập tin không có phần mở rộng.
Lucy

Bạn nhầm định rằng một đường dẫn thư mục sẽ luôn bao gồm "\" cuối cùng. Ví dụ, Path.GetDirectoryName("C:\SomeFolder\SomeSubFolder")sẽ trở lại C:\SomeFolder. Lưu ý rằng các ví dụ của riêng bạn về những gì GetDirectoryName trả về cho thấy rằng nó trả về một đường dẫn không kết thúc bằng dấu gạch chéo ngược. Điều này có nghĩa là nếu ai đó sử dụng GetDirectoryName ở nơi khác để lấy đường dẫn thư mục và sau đó đưa nó vào phương thức của bạn, họ sẽ nhận được câu trả lời sai.
ToolmakerSteve

1

Nếu bạn muốn tìm các thư mục, bao gồm cả những thư mục được đánh dấu "ẩn" và "hệ thống", hãy thử điều này (yêu cầu .NET V4):

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

1

Tôi cần điều này, các bài đăng đã giúp, điều này đưa nó xuống một dòng và nếu đường dẫn hoàn toàn không phải là một đường dẫn, nó chỉ trả về và thoát khỏi phương thức. Nó giải quyết tất cả các mối quan tâm ở trên, cũng không cần dấu gạch chéo.

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

0

Tôi sử dụng như sau, nó cũng kiểm tra phần mở rộng có nghĩa là nó có thể được sử dụng để kiểm tra nếu đường dẫn được cung cấp là một tệp nhưng một tệp không tồn tại.

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

1
Phần mở rộng FileInfo là (IMAO) là một tùy chọn tốt để kiểm tra các đường dẫn không tồn tại
dataCore 21/03/13

2
tình trạng thứ hai của bạn (khác) là có mùi. nếu nó không phải là một tệp hiện có thì bạn không biết nó có thể là gì (các thư mục cũng có thể kết thúc bằng một cái gì đó như ".txt").
nawfal

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

0

Sử dụng câu trả lời được chọn trên bài đăng này, tôi đã xem các bình luận và tin tưởng vào @ ŞafakGür, @Anthony và @Quinn Wilson cho các bit thông tin của họ dẫn tôi đến câu trả lời được cải thiện này mà tôi đã viết và kiểm tra:

    /// <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;
    }

Có vẻ hơi lãng phí khi kiểm tra các thuộc tính sau khi đã kiểm tra Thư mục / Tệp tồn tại ()? Hai cuộc gọi đó làm tất cả các công việc cần thiết ở đây.
Mã hóa

0

Có thể cho UWP C #

public static async Task<IStorageItem> AsIStorageItemAsync(this string iStorageItemPath)
    {
        if (string.IsNullOrEmpty(iStorageItemPath)) return null;
        IStorageItem storageItem = null;
        try
        {
            storageItem = await StorageFolder.GetFolderFromPathAsync(iStorageItemPath);
            if (storageItem != null) return storageItem;
        } catch { }
        try
        {
            storageItem = await StorageFile.GetFileFromPathAsync(iStorageItemPath);
            if (storageItem != null) return storageItem;
        } catch { }
        return storageItem;
    }

0

Tôi hiểu rồi, tôi đã trễ 10 năm cho bữa tiệc. Tôi đã phải đối mặt với tình huống, trong đó từ một số tài sản tôi có thể nhận được tên tệp hoặc đường dẫn tệp đầy đủ. Nếu không có đường dẫn nào được cung cấp, tôi phải kiểm tra sự tồn tại của tệp bằng cách đính kèm đường dẫn thư mục "toàn cầu" được cung cấp bởi một thuộc tính khác.

Trong trường hợp của tôi

var isFileName = System.IO.Path.GetFileName (str) == str;

đã lừa Ok, nó không phải là phép thuật, nhưng có lẽ điều này có thể cứu ai đó vài phút để tìm ra. Vì đây chỉ là một phân tích cú pháp chuỗi, vì vậy tên Dir có dấu chấm có thể cho kết quả dương tính giả ...


0

Đến bữa tiệc rất muộn nhưng tôi thấy Nullable<Boolean>giá trị trả về khá xấu - IsDirectory(string path)trả lại nullkhông tương đương với một con đường không tồn tại mà không bình luận dài dòng, vì vậy tôi đã đưa ra những điều sau:

public static class PathHelper
{
    /// <summary>
    /// Determines whether the given path refers to an existing file or directory on disk.
    /// </summary>
    /// <param name="path">The path to test.</param>
    /// <param name="isDirectory">When this method returns, contains true if the path was found to be an existing directory, false in all other scenarios.</param>
    /// <returns>true if the path exists; otherwise, false.</returns>
    /// <exception cref="ArgumentNullException">If <paramref name="path"/> is null.</exception>
    /// <exception cref="ArgumentException">If <paramref name="path"/> equals <see cref="string.Empty"/></exception>
    public static bool PathExists(string path, out bool isDirectory)
    {
        if (path == null) throw new ArgumentNullException(nameof(path));
        if (path == string.Empty) throw new ArgumentException("Value cannot be empty.", nameof(path));

        isDirectory = Directory.Exists(path);

        return isDirectory || File.Exists(path);
    }
}

Phương pháp trợ giúp này được viết để dài dòng và đủ súc tích để hiểu ý định ngay lần đầu tiên bạn đọc nó.

/// <summary>
/// Example usage of <see cref="PathExists(string, out bool)"/>
/// </summary>
public static void Usage()
{
    const string path = @"C:\dev";

    if (!PathHelper.PathExists(path, out var isDirectory))
        return;

    if (isDirectory)
    {
        // Do something with your directory
    }
    else
    {
        // Do something with your file
    }
}

-4

Điều này có hiệu quả không?

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

1
Điều này sẽ không hoạt động chỉ vì tên thư mục có thể có dấu
chấm

Ngoài ra các tập tin không phải có thời gian trong đó.
Keith Pinson
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.