メソッド | 機能 |
---|---|
CreateDirectory(String) | 指定のディレクトリが存在していないならば、サブディレクトリも含めて作成する。さもなくば何もしない |
CreateDirectory(String, DirectorySecurity) | 指定のセキュリティでディレクトリを作成する。 |
public static DirectoryInfo CreateDirectory(string path)Directory.CreateDirectory メソッド (String) (System.IO) | MSDN
pathにはディレクトリのパスを指定します。これをファイルのパスとすると、それがディレクトリ名と解釈されて作成されます。つまり"c:\dir\sample.txt"
と指定すると、c:\dirにsample.txtの名前のディレクトリが作成されます。これを適切に処理するには、Path.GetDirectoryName()でディレクトリ名の部分のみを取得してから渡すようにします。
Directory.CreateDirectory(Path.GetDirectoryName(path));
ディレクトリをコピーするメソッドは提供されていないため、同名のディレクトリを作成した上で、それに含まれるファイルを1つずつコピーします。例 - DirectoryInfo クラス (System.IO) | Microsoft Learn
public static void Move ( string sourceDirName, string destDirName );Directory.Move(String, String) メソッド (System.IO) | Microsoft Learn
異なる名前で同じディレクトリへ移動することで、ディレクトリ名の変更 (rename) として機能させられます。
Delete()で削除できます。
public static void Delete( string path )
ディレクトリが空ではない場合には次のオーバーロードでrecursiveをtrueとしなければ、「ディレクトリが空ではありません。(The directory is not empty.)」としてSystem.IO.IOExceptionが投げられます。ただしrecursiveをtrueとしても、この例外が投げられることがあります。
public static void Delete( string path, bool recursive )Directory.Delete メソッド (System.IO) | Microsoft Learn
recursiveをtrueとするとサブディレクトリがあるときに再帰的に削除メソッドが呼び出されるため、処理に時間がかかることがあります。
ディレクトリが空であるかは、EnumerateFileSystemEntries()で取得できる列挙子を進めることで効率的に確認できます。io - How to quickly check if folder is empty (.NET)? - Stack Overflow
bool empty = !Directory.EnumerateFileSystemEntries(path).Any();
public static bool Exists (string path);Directory.Exists(String) Method (System.IO) | Microsoft Learn
指定ディレクトリが存在しているならば、trueが返されます。次のような場合はfalseとなります。
確認前に末尾の空白は削除されます。大文字/小文字は区別されません。
string path = @"C:\dir\sample.txt"; bool result1 = Directory.Exists(path); // false bool result2 = Directory.Exists(Path.GetDirectoryName(path)); // true bool result3 = Directory.Exists("sample.txt"); // false
// ファイル名 string[] files1 = Directory.GetFiles(path); string[] files2 = Directory.GetFiles(path, "*.txt"); // パターンに一致するもののみ string[] files3 = Directory.GetFiles(path, "*.txt" , SearchOption.AllDirectories); // サブディレクトリも含める // サブディレクトリ名 string[] directories = Directory.GetDirectories(path); // ファイル名とサブディレクトリ名 string[] fileSystemEntries = Directory.GetFileSystemEntries(path);
メソッド | 機能 |
---|---|
GetFiles(String) | ディレクトリ内のすべてのファイル名を取得できる |
GetDirectories(String) | ディレクトリ内のすべてのサブディレクトリ名を取得できる |
GetFileSystemEntries(String) | ディレクトリ内のすべてのファイル名とサブディレクトリ名を取得できる |
これらのメソッドからは、パスを含むフルネーム (full name) で返されます。これをパスを除いた名前で取得するには、DirectoryInfo.GetFiles()などでFileInfoクラスなどで得て、そのNameプロパティから取得します。
ディレクトリを相対パスで指定したときは結果も相対パスで、絶対パスならば結果も絶対パスで返されます。
public static string[] GetFiles ( string path, string searchPattern, System.IO.SearchOption searchOption );GetFiles(String, String, SearchOption) - Directory.GetFiles メソッド (System.IO) | Microsoft Learn
pathの大文字/小文字は、NTFSでは区別されませんが、Linuxのファイルシステムでは区別されます。
searchPatternの大文字/小文字は、区別されません。「*」と「?」のワイルドカードを指定できます。
searchPattern、searchOptionを省略したときは、それぞれ"*"、SearchOption.TopDirectoryOnlyが指定されます。GetFiles - directory.cs
.NET 4.0以降ならば、より効率的にファイル名などを取得できるEnumerateFiles()などを用います。
メソッド | 機能 |
---|---|
EnumerateFiles(String) | ディレクトリ内のすべてのファイル名の、コレクションを取得できる |
EnumerateDirectories(String) | ディレクトリ内のすべてのサブディレクトリ名の、コレクションを取得できる |
EnumerateFileSystemEntries(String) | ディレクトリ内のすべてのファイル名とサブディレクトリ名の、コレクションを取得できる |
またGetFiles()などで指定できるパターンは単純なものに限られるため、より複雑な条件はEnumerateFiles()などでコレクションとして取得した上で処理します。c# - Can you call Directory.GetFiles() with multiple filters? - Stack Overflow
public static System.Collections.Generic.IEnumerable<string> EnumerateFiles ( string path, string searchPattern, System.IO.SearchOption searchOption );EnumerateFiles(String, String, SearchOption) - Directory.EnumerateFiles メソッド (System.IO) | Microsoft Learn
戻り値はIEnumerable<string>で返されるため、そのままLINQのデータソースとして渡せます。
IEnumerable<string> files = from file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories) where file.EndsWith(".txt") || file.EndsWith(".ini") select file;
また、foreachでそのまま列挙できます。
foreach (string file in Directory.EnumerateFiles(path)) { }
ただし列挙操作中にアクセス権のないファイルがあると、そこでUnauthorizedAccessExceptionが投げられ処理が停止してしまいます。これを回避するには列挙子を進めるときに例外を捕捉し、対処するようにします。
IEnumerable<string> files = Directory.EnumerateFiles(path); using (IEnumerator<string> iterator = files.GetEnumerator()) { while (true) { try { if (!iterator.MoveNext()) break; } catch (UnauthorizedAccessException) { continue; } string file = iterator.Current; } }
public static string GetCurrentDirectory()Directory.GetCurrentDirectory メソッド (System.IO) | MSDN
public static void SetCurrentDirectory( string path )Directory.SetCurrentDirectory メソッド (String) (System.IO) | MSDN
現在の作業ディレクトリ (current working directory) の取得と設定を行えます。これはEnvironment.CurrentDirectoryプロパティへの読み書きでも可能ですが、このプロパティは内部ではDirectoryクラスのメソッドを呼んでいるだけです。CurrentDirectory - environment.cs
設定時には、末尾の空白とバックスラッシュは削除されます。
Directory.SetCurrentDirectory("C:\\dir"); string dir1 = Directory.GetCurrentDirectory(); // "C:\\dir" Directory.SetCurrentDirectory("C:\\dir "); string dir2 = Directory.GetCurrentDirectory(); // "C:\\dir" Directory.SetCurrentDirectory("C:\\dir\\"); string dir3 = Directory.GetCurrentDirectory(); // "C:\\dir"
なおVisual Studioでのデバッグ時に設定するだけならば、プロジェクトのプロパティを開き[デバッグ]タブの[作業ディレクトリ]でも設定できます。ただしこの設定は、単体テストのデバッグには適用されません。C# デバッグ構成のプロジェクト設定 | MSDN
作業ディレクトリは、FileDialogによって変更されることがあります。
AppDomain.CurrentDomain.BaseDirectoryから得られます。c# - Best way to get application folder path - Stack Overflow
またはAssembly.Locationからアプリケーションの実行ファイルのパスを取得し、そのディレクトリ名の部分を取得することでも得られます。c# - How can I get the application's path in a .NET console application? - Stack Overflow
System.Reflection.Assembly assembly = typeof(MyProgram).Assembly; string directory = Path.GetDirectoryName(assembly.Location);
Application.StartupPathからでも得られますが、Visual Studioのテスト環境ではC:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TestWindowのようなディレクトリが返されます。
File.Exists()で真ならばファイル、Directory.Exists()で真ならばディレクトリです。File.Exists メソッド (String) (System.IO) | MSDN
if(File.Exists(path)) { // pathはファイル } else if(Directory.Exists(path)) { // pathはディレクトリ } else { // pathはファイルでもディレクトリでもない }Directory.Exists メソッド (String) (System.IO) | MSDN
なお属性から調べる方法もありますが、この方法では指定のパスが存在しないときにはFileNotFoundExceptionが、ネットワークドライブが存在しないときにはIOExceptionが投げられます。How do I distinguish a file or a folder in a drag and drop event in c#? - Stack Overflow
FileAttributes attributes = File.GetAttributes(path); bool isDirectory = attributes.HasFlag(FileAttributes.Directory);
このときFileInfo.Attributesプロパティから属性を取得しないようにします。このプロパティはパスが存在しないときは-1を返すため、ファイルでもディレクトリでもないときにHasFlag(FileAttributes.Directory)がtrueとなります。
Directory.Exists()も内部では属性で判定しているため、効率を追求するならば、こちらの方法を用います。