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


当前回答

作为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属性中测试项目类型,以避免在单击项目时进行额外的系统调用以获取数据。

其他回答

作为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属性中测试项目类型,以避免在单击项目时进行额外的系统调用以获取数据。

在结合其他答案的建议后,我意识到我得到了和罗尼·奥弗比的答案差不多的东西。以下是一些测试,指出一些需要考虑的问题:

文件夹可以有扩展名:C:\Temp\folder_with.dot 文件不能以目录分隔符(斜杠)结束 从技术上讲,有两个特定于平台的目录分隔符——也就是说,可能是斜杠,也可能不是。和Path.AltDirectorySeparatorChar)

测试(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:\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://stackoverflow.com/questions/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;
}

只是在路径中添加一个边缘大小写-“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;
    }
}

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

对我来说

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

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

如果路径是目录或文件,只需要这一行即可:

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