[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 메소드를 찾고 있었지만 그렇게 할 수 없었습니다. 그러한 방법이 있습니까? 존재하지 않는 경우 경로가 파일인지 디렉토리인지를 결정하는 가장 간단한 방법은 무엇입니까?



답변

에서 어떻게 경로가 파일 또는 디렉터리 인 경우 알려줄 수 :

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


답변

내 꺼야 :

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

다른 사람들의 대답과 비슷하지만 정확히 동일하지는 않습니다.


답변

Directory.Exists () 대신 File.GetAttributes () 메서드를 사용하여 파일 또는 디렉터리의 특성을 가져올 수 있으므로 다음과 같은 도우미 메서드를 만들 수 있습니다.

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 속성에서 항목 유형을 테스트하여 항목을 클릭 할 때 해당 데이터를 얻기 위해 추가 시스템 호출을 저장할 수 있습니다.


답변

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


답변

다른 답변의 제안을 결합한 후 Ronnie Overby의 답변 과 동일한 내용을 생각해 냈습니다 . 다음은 몇 가지 고려해야 할 사항을 지적하는 테스트입니다.

  1. 폴더에는 “확장자”가있을 수 있습니다. C:\Temp\folder_with.dot
  2. 파일은 디렉토리 구분 기호 (슬래시)로 끝날 수 없습니다
  3. 기술적으로 플랫폼에 따라 두 개의 디렉토리 구분 기호가 있습니다 (예 : 슬래시 이거나 아닐 수 있음)Path.DirectorySeparatorCharPath.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)
{
    // /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;
}