78

パスがあり、それがディレクトリかファイルかを判断する必要があります。

パスがファイルかどうかを判断するには、これが最善の方法ですか?

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

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

ディレクトリの場合、ロジックを逆にします。

string directory = @"C:\Test";

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

両方が存在しない場合は、どちらのブランチも実行しません。したがって、両方が存在すると仮定します。

4

8 に答える 8

122

使用する:

System.IO.File.GetAttributes(string path)

返さFileAttributesれた結果に値が含まれているかどうかを確認しますFileAttributes.Directory

bool isDir = (File.GetAttributes(path) & FileAttributes.Directory)
                 == FileAttributes.Directory;
于 2009-01-13T15:52:09.947 に答える
57

これは、2つのチェックだけが必要な最も簡単な方法だと思います。

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
}
于 2009-01-13T16:00:14.547 に答える
11

これは、いくつかの相互運用コードを使用して行うことができます。

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

コメントのいくつかをさらに明確にするために...

これにアンマネージコードを導入することは、他のファイルや.NETのI / O関連の呼び出しよりも本質的に危険ではありません。これは、すべてがアンマネージコードを呼び出すためです。

これは、文字列を使用した単一の関数呼び出しです。この関数を呼び出して、新しいデータ型やメモリ使用量を導入することはありません。はい、適切にクリーンアップするにはアンマネージコードに依存する必要がありますが、最終的にはほとんどのI/O関連の呼び出しに依存します。

参考までに、ReflectorからFile.GetAttributes(文字列パス)へのコードは次のとおりです。

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

ご覧のとおり、ファイル属性を取得するためにアンマネージコードも呼び出しているため、アンマネージコードの導入が危険であるという主張は無効です。同様に、マネージコードに完全にとどまることについての議論。これを行うためのマネージコードの実装はありません。他の回答が提案しているようにFile.GetAttributes()を呼び出すことでさえ、管理されていないコードを呼び出すことと同じ「問題」があり、これがパスがディレクトリであるかどうかを判断するためのより信頼できる方法であると思います。

編集CASに関する@ChristianKのコメントに回答します。GetAttributesがセキュリティを要求する唯一の理由は、ファイルのプロパティを読み取る必要があるため、呼び出し元のコードにそのためのアクセス許可があることを確認する必要があるためだと思います。これは、基盤となるOSチェック(存在する場合)と同じではありません。必要に応じて、特定のCAS権限も要求するPathIsDirectoryへのP/Invoke呼び出しの周りにラッパー関数をいつでも作成できます。

于 2009-01-13T15:50:57.297 に答える
7

ディレクトリが存在すると仮定します...

bool isDir = (File.GetAttributes(path) & FileAttributes.Directory)
                  == FileAttributes.Directory;
于 2009-01-13T15:52:32.003 に答える
4

これをチェックしてください:

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

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

于 2009-01-13T15:54:05.370 に答える
2

ファイル属性を読み取ります。

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

ディレクトリフラグを確認します。

于 2009-01-13T15:54:42.157 に答える
1

特定のパス文字列がディレクトリファイルの両方を表すことができない場合、以下は問題なく機能し、他の操作への扉を開きます。

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

ファイルシステムを使用している場合は、FileInfo文字DirectoryInfo列を使用するよりも、を使用する方がはるかに簡単です。

于 2009-01-13T15:55:43.400 に答える
-4

うーん、Files( の) クラスjava.nioには実際に静的isDirectoryメソッドがあるようです。したがって、実際には次のように使用できると思います。

Path what = ...
boolean isDir = Files.isDirectory(what);
于 2013-01-10T20:20:37.050 に答える