我正在处理目录和文件的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方法来处理这个问题,但我还没有能够这样做。是否存在这样的方法,如果不存在,确定路径是文件还是目录的最直接的方法是什么?


当前回答

只是在路径中添加一个边缘大小写-“Folder Selection.”

在我的应用程序中,我得到了传递给我的最近打开的路径,其中一些路径的末尾有“文件夹选择”。

一些fileopendialog和WinMerge会在路径中添加“文件夹选择”(这是真的)。

但在Windows操作系统下,“文件夹选择”并不是一个建议的文件或文件夹名称(就像“不要这样做,永远不要抖拳头”一样)。 如这里所说:http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx

不要以空格或句号结束文件或目录名。虽然底层文件系统可能支持这样的名称,但Windows shell和用户界面不支持。但是,将句点指定为名称的第一个字符是可以接受的。例如,“。temp”。

因此,虽然“Folder Selection.”不应该使用,但它可以使用。(太棒了)。

足够的解释-我的代码(我很喜欢枚举):

public static class Utility
{
    public enum ePathType
    {
        ePathType_Unknown = 0,
        ePathType_ExistingFile = 1,
        ePathType_ExistingFolder = 2,
        ePathType_ExistingFolder_FolderSelectionAdded = 3,
    }

    public static ePathType GetPathType(string path)
    {
        if (File.Exists(path) == true) { return ePathType.ePathType_ExistingFile; }
        if (Directory.Exists(path) == true) { return ePathType.ePathType_ExistingFolder; }

        if (path.EndsWith("Folder Selection.") == true)
        {
            // Test the path again without "Folder Selection."
            path = path.Replace("\\Folder Selection.", "");
            if (Directory.Exists(path) == true)
            {
                // Could return ePathType_ExistingFolder, but prefer to let the caller known their path has text to remove...
                return ePathType.ePathType_ExistingFolder_FolderSelectionAdded;
            }
        }

        return ePathType.ePathType_Unknown;
    }
}

其他回答

这是我所能想到的最好的Exists和Attributes属性的行为:

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

很晚才到这里,但我发现Nullable<Boolean>返回值相当难看- IsDirectory(字符串路径)返回null并不等于没有详细注释的不存在的路径,所以我提出了以下内容:

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

这个helper方法写得足够冗长和简洁,以便在第一次阅读时就能理解其意图。

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

作为directory . exists()的替代方法,你可以使用file . getattributes()方法来获取文件或目录的属性,所以你可以创建一个像这样的helper方法:

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

在填充包含该项的附加元数据的控件时,还可以考虑向TreeView控件的tag属性添加对象。例如,您可以为文件添加FileInfo对象,为目录添加DirectoryInfo对象,然后在tag属性中测试项目类型,以避免在单击项目时进行额外的系统调用以获取数据。

我明白了,我迟到了10年。 我面临的情况是,从某些属性中,我可以接收文件名或完整的文件路径。如果没有提供路径,我必须通过附加由另一个属性提供的“全局”目录路径来检查文件的存在性。

对我来说

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

成功了。 好吧,这不是魔法,但也许这可以为某人节省几分钟的思考时间。 因为这只是一个字符串解析,所以带点的diri -names可能会给出假阳性…

我需要这个,posts帮助它,这让它变成一行,如果路径根本不是路径,它就会返回并退出方法。它解决了上述所有问题,也不需要后面的斜杠。

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