.NET如何检查路径是否是文件而不是目录?

时间:2021-12-04 00:04:04

I have a path and I need to determine if it is a directory or file.

我有一个路径,我需要确定它是目录还是文件。

Is this the best way to determine if the path is a file?

这是确定路径是否是文件的最佳方式吗?

string file = @"C:\Test\foo.txt";

bool isFile = !System.IO.Directory.Exists(file) && 
                         System.IO.File.Exists(file);

For a directory I would reverse the logic.

对于一个目录,我将反转逻辑。

string directory = @"C:\Test";

bool isDirectory = System.IO.Directory.Exists(directory) && 
                            !System.IO.File.Exists(directory);

If both don't exists that then I won't go do either branch. So assume they both do exists.

如果两者都不存在,那么我不会去做任何一个分支。假设它们都存在。

8 个解决方案

#1


104  

Use:

使用:

System.IO.File.GetAttributes(string path)

and check whether the returned FileAttributes result contains the value FileAttributes.Directory:

检查返回的文件属性结果是否包含值FileAttributes.Directory:

bool isDir = (File.GetAttributes(path) & FileAttributes.Directory)
                 == FileAttributes.Directory;

#2


46  

I think this is the simplest way where you only need two checks:

我认为这是最简单的方法,你只需要两张支票:

string file = @"C:\tmp";
if (System.IO.Directory.Exists(file))
{
    // do stuff when file is an existing directory
}
else if (System.IO.File.Exists(file))
{
    // do stuff when file is an existing file
}

#3


10  

You can do this with some interop code:

你可以用一些interop代码来做这个:

    [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
    [return: MarshalAsAttribute(UnmanagedType.Bool)]
    public static extern bool PathIsDirectory([MarshalAsAttribute(UnmanagedType.LPWStr), In] string pszPath);

To further clarify some of the comments...

为了进一步澄清一些评论……

Introducing unmanaged code in this is not any more inherintly dangerous than any of the other file or I/O related calls in .NET since they ultimatley all call in to unmanaged code.

在这种情况下引入非托管代码并不比在。net中引入任何其他文件或I/O相关调用更危险,因为它们最后都会调用非托管代码。

This is a single function call using a string. You aren't introducing any new data types and/or memory usage by calling this function. Yes, you do need to rely on the unmanaged code to properly clean up, but you ultimately have that dependency on most of the I/O related calls.

这是一个使用字符串的函数调用。通过调用这个函数,您不会引入任何新的数据类型和/或内存使用。是的,您确实需要依赖非托管代码来正确清理,但是您最终会依赖于大多数与I/O相关的调用。

For reference, here is the code to File.GetAttributes(string path) from Reflector:

作为参考,这里是要归档的代码。从反射器GetAttributes(string路径):

public static FileAttributes GetAttributes(string path)
{
    string fullPathInternal = Path.GetFullPathInternal(path);
    new FileIOPermission(FileIOPermissionAccess.Read, new string[] { fullPathInternal }, false, false).Demand();
    Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
    int errorCode = FillAttributeInfo(fullPathInternal, ref data, false, true);
    if (errorCode != 0)
    {
        __Error.WinIOError(errorCode, fullPathInternal);
    }
    return (FileAttributes) data.fileAttributes;
}

As you can see, it is also calling in to unmanaged code in order to retrieve the file attributes, so the arguements about introducing unmanaged code being dangerous are invalid. Likewise, the argument about staying completely in managed code. There is no managed code implementation to do this. Even calling File.GetAttributes() as the other answers propose have the same "issues" of calling unmanged code and I believe this is the more reliable method to accomplish determining if a path is a directory.

如您所见,它还调用非托管代码来检索文件属性,因此关于引入非托管代码危险的争论是无效的。同样,关于完全保留在托管代码中的争论。没有托管代码实现可以做到这一点。即使像其他答案建议的那样调用File.GetAttributes(),也存在调用未执行代码的“问题”,我认为这是更可靠的方法,可以确定路径是否是一个目录。

Edit To answer the comment by @Christian K about CAS. I believe the only reason GetAttributes makes the security demand is because it needs to read the properties of the file so it wants to make sure the calling code has permission to do so. This is not the same as the underlying OS checks (if there are any). You can always create a wrapper function around the P/Invoke call to PathIsDirectory that also demands certain CAS permissions, if necessary.

编辑回复@Christian K关于CAS的评论。我认为,GetAttributes之所以提出安全性要求,是因为它需要读取文件的属性,因此它希望确保调用代码具有这样做的权限。这与底层OS检查不同(如果有的话)。您总是可以围绕对PathIsDirectory的P/Invoke调用创建一个包装函数,该调用还需要特定的CAS权限(如果需要的话)。

#4


7  

Assuming the directory exists...

假设目录存在……

bool isDir = (File.GetAttributes(path) & FileAttributes.Directory)
                  == FileAttributes.Directory;

#5


3  

Check this out:

看看这个:

/// <summary>
/// Returns true if the given file path is a folder.
/// </summary>
/// <param name="Path">File path</param>
/// <returns>True if a folder</returns>
public bool IsFolder(string path)
{
    return ((File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory);
}

from http://www.jonasjohn.de/snippets/csharp/is-folder.htm

从http://www.jonasjohn.de/snippets/csharp/is-folder.htm

#6


2  

Read the file attributes:

读取文件属性:

FileAttributes att = System.IO.File.GetAttributes(PATH_TO_FILE);

Check for the Directory flag.

检查目录标志。

#7


1  

Given that a particular path string cannot represent both a directory and a file, then the following works just fine and opens the door for other operations.

给定一个特定的路径字符串不能同时表示一个目录和一个文件,那么下面的操作就可以很好地工作,并为其他操作打开大门。

bool isFile = new FileInfo(path).Exists;
bool isDir = new DirectoryInfo(path).Exists;

If you're working with the file system, using FileInfo and DirectoryInfo is much simpler than using strings.

如果使用文件系统,使用FileInfo和DirectoryInfo要比使用字符串简单得多。

#8


-2  

Hmm, it looks like the Files class (in java.nio) actually has a static isDirectory method. So, I think you could actually use the following:

嗯,看起来file类(在java.nio中)实际上有一个静态isDirectory方法。所以,我认为你可以用以下方法:

Path what = ...
boolean isDir = Files.isDirectory(what);

#1


104  

Use:

使用:

System.IO.File.GetAttributes(string path)

and check whether the returned FileAttributes result contains the value FileAttributes.Directory:

检查返回的文件属性结果是否包含值FileAttributes.Directory:

bool isDir = (File.GetAttributes(path) & FileAttributes.Directory)
                 == FileAttributes.Directory;

#2


46  

I think this is the simplest way where you only need two checks:

我认为这是最简单的方法,你只需要两张支票:

string file = @"C:\tmp";
if (System.IO.Directory.Exists(file))
{
    // do stuff when file is an existing directory
}
else if (System.IO.File.Exists(file))
{
    // do stuff when file is an existing file
}

#3


10  

You can do this with some interop code:

你可以用一些interop代码来做这个:

    [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
    [return: MarshalAsAttribute(UnmanagedType.Bool)]
    public static extern bool PathIsDirectory([MarshalAsAttribute(UnmanagedType.LPWStr), In] string pszPath);

To further clarify some of the comments...

为了进一步澄清一些评论……

Introducing unmanaged code in this is not any more inherintly dangerous than any of the other file or I/O related calls in .NET since they ultimatley all call in to unmanaged code.

在这种情况下引入非托管代码并不比在。net中引入任何其他文件或I/O相关调用更危险,因为它们最后都会调用非托管代码。

This is a single function call using a string. You aren't introducing any new data types and/or memory usage by calling this function. Yes, you do need to rely on the unmanaged code to properly clean up, but you ultimately have that dependency on most of the I/O related calls.

这是一个使用字符串的函数调用。通过调用这个函数,您不会引入任何新的数据类型和/或内存使用。是的,您确实需要依赖非托管代码来正确清理,但是您最终会依赖于大多数与I/O相关的调用。

For reference, here is the code to File.GetAttributes(string path) from Reflector:

作为参考,这里是要归档的代码。从反射器GetAttributes(string路径):

public static FileAttributes GetAttributes(string path)
{
    string fullPathInternal = Path.GetFullPathInternal(path);
    new FileIOPermission(FileIOPermissionAccess.Read, new string[] { fullPathInternal }, false, false).Demand();
    Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
    int errorCode = FillAttributeInfo(fullPathInternal, ref data, false, true);
    if (errorCode != 0)
    {
        __Error.WinIOError(errorCode, fullPathInternal);
    }
    return (FileAttributes) data.fileAttributes;
}

As you can see, it is also calling in to unmanaged code in order to retrieve the file attributes, so the arguements about introducing unmanaged code being dangerous are invalid. Likewise, the argument about staying completely in managed code. There is no managed code implementation to do this. Even calling File.GetAttributes() as the other answers propose have the same "issues" of calling unmanged code and I believe this is the more reliable method to accomplish determining if a path is a directory.

如您所见,它还调用非托管代码来检索文件属性,因此关于引入非托管代码危险的争论是无效的。同样,关于完全保留在托管代码中的争论。没有托管代码实现可以做到这一点。即使像其他答案建议的那样调用File.GetAttributes(),也存在调用未执行代码的“问题”,我认为这是更可靠的方法,可以确定路径是否是一个目录。

Edit To answer the comment by @Christian K about CAS. I believe the only reason GetAttributes makes the security demand is because it needs to read the properties of the file so it wants to make sure the calling code has permission to do so. This is not the same as the underlying OS checks (if there are any). You can always create a wrapper function around the P/Invoke call to PathIsDirectory that also demands certain CAS permissions, if necessary.

编辑回复@Christian K关于CAS的评论。我认为,GetAttributes之所以提出安全性要求,是因为它需要读取文件的属性,因此它希望确保调用代码具有这样做的权限。这与底层OS检查不同(如果有的话)。您总是可以围绕对PathIsDirectory的P/Invoke调用创建一个包装函数,该调用还需要特定的CAS权限(如果需要的话)。

#4


7  

Assuming the directory exists...

假设目录存在……

bool isDir = (File.GetAttributes(path) & FileAttributes.Directory)
                  == FileAttributes.Directory;

#5


3  

Check this out:

看看这个:

/// <summary>
/// Returns true if the given file path is a folder.
/// </summary>
/// <param name="Path">File path</param>
/// <returns>True if a folder</returns>
public bool IsFolder(string path)
{
    return ((File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory);
}

from http://www.jonasjohn.de/snippets/csharp/is-folder.htm

从http://www.jonasjohn.de/snippets/csharp/is-folder.htm

#6


2  

Read the file attributes:

读取文件属性:

FileAttributes att = System.IO.File.GetAttributes(PATH_TO_FILE);

Check for the Directory flag.

检查目录标志。

#7


1  

Given that a particular path string cannot represent both a directory and a file, then the following works just fine and opens the door for other operations.

给定一个特定的路径字符串不能同时表示一个目录和一个文件,那么下面的操作就可以很好地工作,并为其他操作打开大门。

bool isFile = new FileInfo(path).Exists;
bool isDir = new DirectoryInfo(path).Exists;

If you're working with the file system, using FileInfo and DirectoryInfo is much simpler than using strings.

如果使用文件系统,使用FileInfo和DirectoryInfo要比使用字符串简单得多。

#8


-2  

Hmm, it looks like the Files class (in java.nio) actually has a static isDirectory method. So, I think you could actually use the following:

嗯,看起来file类(在java.nio中)实际上有一个静态isDirectory方法。所以,我认为你可以用以下方法:

Path what = ...
boolean isDir = Files.isDirectory(what);