2013-11-30T21:59:48の更新内容

programming/netfx/filesystem/1_filesystem/index.wiki.txt

current previous
1,1457 0,0
+
${smdncms:title,ファイル・ディレクトリの操作}
+
${smdncms:header_title,ファイル・ディレクトリの操作 (System.IO)}
+
${smdncms:keywords,File,Directory,FileInfo,DirectoryInfo,DriveInfo,ファイル,フォルダ,ディレクトリ,パス,削除,移動,コピー,検索,走査}
+
${smdncms:document_versions,codelang=cs,codelang=vb}
+

          
+
#navi(..)
+

          
+
&msdn(netfx,ns,System.IO){System.IO名前空間};に用意されているクラスを使うことでファイルやディレクトリ(フォルダ)などファイルシステムに対する操作を行うことができます。 例えば、ファイルのコピー・削除・移動などの操作は[[Fileクラス>#File]]、ディレクトリの作成・削除・移動などの操作は[[Directoryクラス>#Directory]]のメソッドを使います。 また、[[FileInfo・DirectoryInfo>#Info_classes]]のインスタンスを作成・取得することでファイルやディレクトリのプロパティを取得することもできます。
+

          
+
ここではファイルシステムに対する操作とSystem.IO名前空間にあるクラスのうち、ファイルシステムの操作に関するクラスの使い方について解説します。 ファイルに対する読み込み・書き込みについては[[programming/netfx/stream/1_1_filestream]]や[[programming/netfx/stream/2_streamreader_streamwriter]]にて個別に解説していますのでそちらをご覧ください。
+

          
+
なお、ここでは''フォルダ''という用語は使わずクラス名にも使われている''ディレクトリ''で統一します。
+

          
+
-関連するページ
+
--[[programming/netfx/stream/1_1_filestream]]
+
--[[programming/netfx/stream/2_streamreader_streamwriter]]
+

          
+
#googleadunit
+

          
+
本文中のサンプルではパスを記述するために[[逐語的文字列リテラル>programming/netfx/basic_types/1_literal_suffix#VerbatimStringLiterals]]を使用している個所があります。
+

          
+

          
+

          
+
*ディレクトリの走査・ファイルの検索 [#Directory.GetFileSystemEntries]
+
ディレクトリを走査してディレクトリ内に含まれるファイルやサブディレクトリを取得するには、Directoryクラスに用意されているメソッドを使います。 単純な走査だけでなく、ワイルドカードによるパターンマッチングを使った検索や、ディレクトリ内の再帰的な走査も行うことができます。
+

          
+
ディレクトリ内にあるすべてのファイルを取得するには&msdn(netfx,member,System.IO.Directory.GetFiles){GetFilesメソッド};、サブディレクトリを取得するには&msdn(netfx,member,System.IO.Directory.GetDirectories){GetDirectoriesメソッド};を使います。 これらのメソッドでは、引数として取得の対象となるディレクトリを相対パスまたは絶対パスで指定します。 存在しないディレクトリを指定した場合は例外&msdn(netfx,type,System.IO.DirectoryNotFoundException){DirectoryNotFoundException};がスローされます。
+

          
+
#tabpage(codelang=cs,container-title=ディレクトリ内の全ファイル・サブディレクトリの取得)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // ディレクトリE:\dirにあるすべてのファイルを取得する
+
    string[] files = Directory.GetFiles(@"E:\dir");
+

          
+
    foreach (string file in files) {
+
      Console.WriteLine(file);
+
    }
+

          
+
    // ディレクトリE:\dirにあるすべてのサブディレクトリを取得する
+
    string[] dirs = Directory.GetDirectories(@"E:\dir");
+

          
+
    foreach (string dir in dirs) {
+
      Console.WriteLine(dir);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' ディレクトリE:\dirにあるすべてのファイルを取得する
+
    Dim files() As String = Directory.GetFiles("E:\dir")
+

          
+
    For Each file As String In files
+
      Console.WriteLine(file)
+
    Next
+

          
+
    ' ディレクトリE:\dirにあるすべてのサブディレクトリを取得する
+
    Dim dirs() As String = Directory.GetDirectories("E:\dir")
+

          
+
    For Each dir As String In dirs
+
      Console.WriteLine(dir)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果例){{
+
E:\dir\file1.txt
+
E:\dir\file2.bmp
+
E:\dir\file3.dat
+
E:\dir\subdir1
+
E:\dir\subdir2
+
}}
+

          
+
GetFiles・GetDirectoriesメソッドで特にオプションを指定しない場合、取得されるのは''指定したディレクトリ直下にあるファイル・サブディレクトリ''のみとなります。 この動作を変更するには[[後述するSearchOption>#SearchOption]]を指定する必要があります。
+

          
+
&msdn(netfx,member,System.IO.Directory.GetFileSystemEntries){GetFileSystemEntriesメソッド};を使うと指定ディレクトリにあるファイルとサブディレクトリの両方をまとめて取得することができます。 このメソッドはGetFilesとGetDirectoriesの結果を組み合わせたものと同等となります。
+

          
+
#tabpage(codelang=cs,container-title=GetFileSystemEntriesを使ってディレクトリ内の全ファイル・サブディレクトリの取得する)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // ディレクトリE:\dirにあるすべてのファイルとサブディレクトリを取得する
+
    string[] entries = Directory.GetFileSystemEntries(@"E:\dir");
+

          
+
    foreach (string entry in entries) {
+
      Console.WriteLine(entry);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' ディレクトリE:\dirにあるすべてのファイルとサブディレクトリを取得する
+
    Dim entries() As String = Directory.GetFileSystemEntries("E:\dir")
+

          
+
    For Each entry As String In entries
+
      Console.WriteLine(entry)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果例){{
+
E:\dir\file1.txt
+
E:\dir\file2.bmp
+
E:\dir\file3.dat
+
E:\dir\subdir1
+
E:\dir\subdir2
+
}}
+

          
+

          
+
**ワイルドカードを指定した検索
+
GetFiles・GetDirectories・GetFileSystemEntriesの各メソッドは引数にワイルドカードを指定することにより、ワイルドカードにマッチするファイル・サブディレクトリだけを取得するようにすることもできます。 引数にワイルドカードを指定しない場合はすべてのファイル・サブディレクトリが取得されます。 ``*``を指定した場合も同様にすべてのファイル・サブディレクトリが取得されます。
+

          
+
#tabpage(codelang=cs,container-title=ワイルドカードを用いたファイル・サブディレクトリの取得)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // カレントディレクトリにあるすべてのファイルを取得する
+
    Console.WriteLine("[*]");
+

          
+
    foreach (string file in Directory.GetFiles(".", "*")) {
+
      Console.WriteLine(file);
+
    }
+

          
+
    // カレントディレクトリにあるすべての.txtファイルを取得する
+
    Console.WriteLine("[*.txt]");
+

          
+
    foreach (string file in Directory.GetFiles(".", "*.txt")) {
+
      Console.WriteLine(file);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' カレントディレクトリにあるすべてのファイルを取得する
+
    Console.WriteLine("[*]")
+

          
+
    For Each file As String In Directory.GetFiles(".", "*")
+
      Console.WriteLine(file)
+
    Next
+

          
+
    ' カレントディレクトリにあるすべての.txtファイルを取得する
+
    Console.WriteLine("[*.txt]")
+

          
+
    For Each file As String In Directory.GetFiles(".", "*.txt")
+
      Console.WriteLine(file)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
[*]
+
.\file1.txt
+
.\file2.bmp
+
.\file3.dat
+
[*.txt]
+
.\file1.txt
+
}}
+

          
+
ワイルドカードには任意の1文字を表す``?``および任意の0文字以上を表す``*``を含めることができます。
+

          
+
GetFilesメソッド・GetDirectoriesメソッドでは[[正規表現>programming/netfx/regex]]を使ったマッチングはできないので、必要な場合はワイルドカードを指定する代わりに[[Regexクラス>programming/netfx/regex/0_abstract]]を使って独自にコードを記述する必要があります。
+

          
+

          
+
**ディレクトリ走査のオプション (SearchOption) [#SearchOption]
+
引数に&msdn(netfx,type,System.IO.SearchOption){SearchOption};を指定することにより、サブディレクトリを再帰的に走査するかどうかを指定することができます。 ``SearchOption.TopDirectoryOnly``を指定した場合は対象のディレクトリ直下のみを走査し、``SearchOption.AllDirectories``を指定した場合は対象のディレクトリ内とそのサブディレクトリすべてを再帰的に走査します。
+

          
+
#tabpage(codelang=cs,container-title=SearchOptionを指定したディレクトリ内の走査)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    string[] files;
+

          
+
    // カレントディレクトリ直下にあるすべてのファイルを取得する
+
    Console.WriteLine("[TopDirectoryOnly]");
+

          
+
    files = Directory.GetFiles(".", "*", SearchOption.TopDirectoryOnly);
+

          
+
    foreach (string file in files) {
+
      Console.WriteLine(file);
+
    }
+

          
+
    // カレントディレクトリとそのサブディレクトリ内にあるすべてのファイルを取得する
+
    Console.WriteLine("[AllDirectories]");
+

          
+
    files = Directory.GetFiles(".", "*", SearchOption.AllDirectories);
+

          
+
    foreach (string file in files) {
+
      Console.WriteLine(file);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim files() As String
+

          
+
    ' カレントディレクトリ直下にあるすべてのファイルを取得する
+
    Console.WriteLine("[TopDirectoryOnly]")
+

          
+
    files = Directory.GetFiles(".", "*", SearchOption.TopDirectoryOnly)
+

          
+
    For Each file As String In files
+
      Console.WriteLine(file)
+
    Next
+

          
+
    ' カレントディレクトリとそのサブディレクトリ内にあるすべてのファイルを取得する
+
    Console.WriteLine("[AllDirectories]")
+

          
+
    files = Directory.GetFiles(".", "*", SearchOption.AllDirectories)
+

          
+
    For Each file As String In files
+
      Console.WriteLine(file)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
[TopDirectoryOnly]
+
.\file1.txt
+
.\file2.bmp
+
.\file3.dat
+
[AllDirectories]
+
.\file1.txt
+
.\file2.bmp
+
.\file3.dat
+
.\subdir1\bar.txt
+
.\subdir1\baz.txt
+
.\subdir1\foo.txt
+
.\subdir2\hoge.dat
+
}}
+

          
+

          
+
**列挙子によるディレクトリの走査 [#Directory.EnumerateFileSystemEntries]
+
ファイル・ディレクトリの走査するメソッドにはGetFiles/GetDirectories/GetFileSystemEntriesだけでなく&msdn(netfx,member,System.IO.Directory.EnumerateFiles){EnumerateFiles};/&msdn(netfx,member,System.IO.Directory.EnumerateDirectories){EnumerateDirectories};/&msdn(netfx,member,System.IO.Directory.EnumerateFileSystemEntries){EnumerateFileSystemEntries};というメソッドも用意されています。 これは.NET Framework 4で追加されたメソッドで、どちらも基本的な使い方や得られる結果は同じですが、動作が異なります。
+

          
+
GetFilesメソッドは見つかったファイル・ディレクトリを配列で返すのに対して、EnumerateFilesメソッドは[[IEnumerable<string>>programming/netfx/enumeration]]で返します。 GetFilesメソッドではすべてのファイル・ディレクトリの走査が終わるまで結果が返されないのに対して、EnumerateFilesメソッドではメソッドの呼び出し自体は即座に終了し、走査はIEnumerable<string>を列挙する際に開始され、見つかったファイルが順次返されます。 従って、条件に一致するもののうち最初に見つかったものだけを取得したい場合などにはEnumerateFilesメソッドを使った方が効率的です。
+

          
+
#tabpage(codelang=cs,container-title=EnumerateFilesを使ったディレクトリの走査)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 最初に見つかった.txtファイルを表示する
+
    foreach (string file in Directory.GetFiles(".", "*.txt")) {
+
      Console.WriteLine(file);
+
      break; // 列挙を中断する
+
    }
+

          
+
    // 最初に見つかった.txtファイルを表示する
+
    foreach (string file in Directory.EnumerateFiles(".", "*.txt")) {
+
      Console.WriteLine(file);
+
      break; // 列挙を中断する
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 最初に見つかった.txtファイルを表示する
+
    For Each file As String In Directory.GetFiles(".", "*.txt")
+
      Console.WriteLine(file)
+
      Exit For ' 列挙を中断する
+
    Next
+

          
+
    ' 最初に見つかった.txtファイルを表示する
+
    For Each file As String In Directory.EnumerateFiles(".", "*.txt")
+
      Console.WriteLine(file)
+
      Exit For ' 列挙を中断する
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
上記のコードでは実行結果はどちらも同じとなりますが、仮にディレクトリ内に多数のファイルがある場合、GetFilesメソッドではそのすべてを含む配列が返されるまで列挙が始まらないのに対し、EnumerateFilesでは見つかったファイルから順次列挙されていくことになります。 従って、一般的にGetFilesよりもEnumerateFilesを使った方がよいパフォーマンスが得られます。
+

          
+
一方、EnumerateFilesメソッドから返されるIEnumerable<string>は、列挙を行う度にディレクトリが再走査されます。 従って、EnumerateFilesメソッドで得られる結果を何度も列挙するような場合には、EnumerateFilesよりもGetFilesメソッドを使ったほうがよいパフォーマンスが得られます。
+

          
+
GetFiles/EnumerateFilesだけでなく、GetDirectories/EnumerateDirectoriesおよびGetFileSystemEntries/EnumerateFileSystemEntriesでもこのような特性となります。
+

          
+

          
+

          
+
*ディレクトリに対する操作 (Directoryクラス) [#Directory]
+
ディレクトリの作成・削除・移動などの操作を行うには&msdn(netfx,type,System.IO.Directory){Directoryクラス};のメソッドを使います。
+

          
+
**存在するか調べる (Directory.Exists) [#Directory.Exists]
+
ディレクトリが存在するかどうかを確かめるには&msdn(netfx,member,System.IO.Directory.Exists){Existsメソッド};を使用します。
+

          
+
#tabpage(codelang=cs,container-title=ディレクトリが存在するかどうか調べる)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // ディレクトリE:\dir\が存在するか調べる
+
    if (Directory.Exists(@"E:\dir"))
+
      Console.WriteLine("ディレクトリは存在します");
+

          
+
    // カレントディレクトリにディレクトリsubdirが存在するか調べる
+
    if (Directory.Exists("subdir"))
+
      Console.WriteLine("ディレクトリは存在します");
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' ディレクトリE:\dir\が存在するか調べる
+
    If Directory.Exists("E:\dir") Then
+
      Console.WriteLine("ディレクトリは存在します")
+
    End If
+

          
+
    ' カレントディレクトリにディレクトリsubdirが存在するか調べる
+
    If Directory.Exists("subdir") Then
+
      Console.WriteLine("ディレクトリは存在します")
+
    End If
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
**作成 (Directory.CreateDirectory) [#Directory.CreateDirectory]
+
ディレクトリを作成するには&msdn(netfx,member,System.IO.Directory.CreateDirectory){CreateDirectoryメソッド};を使用します(メソッド名はCreateではないので注意)。 このメソッドでは引数で指定した名前のディレクトリが作成されますが、指定したディレクトリ名が階層をなす場合(``dir\subdir1\subdir2``などサブディレクトリを含む場合)はサブディレクトリも含めて一度に作成されます。 このメソッドは、作成されたディレクトリ(既に存在している場合はそのディレクトリ)の[[DirectoryInfo>#DirectoryInfo]]を返します。
+

          
+
#tabpage(codelang=cs,container-title=ディレクトリを作成する)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // ディレクトリE:\dirを作成する
+
    Directory.CreateDirectory(@"E:\dir");
+

          
+
    // カレントディレクトリにsubdir1\subdir2を作成する
+
    Directory.CreateDirectory(@"subdir1\subdir2");
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' ディレクトリE:\dirを作成する
+
    Directory.CreateDirectory("E:\dir")
+

          
+
    ' カレントディレクトリにsubdir1\subdir2を作成する
+
    Directory.CreateDirectory("subdir1\subdir2")
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
CreateDirectoryメソッドはすでにディレクトリが存在する場合でも例外はスローされずメソッドは成功します。 そのため、事前にディレクトリが存在するかチェックし、存在しない場合のみCreateDirectoryメソッドで作成する、といったことをする必要はありません。
+

          
+
#tabpage(codelang=cs,container-title=ディレクトリを作成する)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // カレントディレクトリにsubdir1\subdir2が存在しない場合のみ作成する
+
    Directory.CreateDirectory(@"subdir1\subdir2");
+

          
+
    // ディレクトリが存在していてもCreateDirectoryは例外をスローしないので、
+
    // 以下のように作成前にDirectory.Existsで存在するかチェックする必要はない
+
    if (!Directory.Exists(@"subdir1\subdir2"))
+
      Directory.CreateDirectory(@"subdir1\subdir2");
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' カレントディレクトリにsubdir1\subdir2が存在しない場合のみ作成する
+
    Directory.CreateDirectory("subdir1\subdir2")
+

          
+
    ' ディレクトリが存在していてもCreateDirectoryは例外をスローしないので、
+
    ' 以下のように作成前にDirectory.Existsで存在するかチェックする必要はない
+
    If Not Directory.Exists("subdir1\subdir2") Then
+
      Directory.CreateDirectory("subdir1\subdir2")
+
    End If
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+

          
+
**削除 (Directory.Delete) [#Directory.Delete]
+
ディレクトリを削除するには&msdn(netfx,member,System.IO.Directory.Delete){Deleteメソッド};を使用します。 このメソッドは対象のディレクトリが空の場合のみディレクトリを削除できます。 対象のディレクトリにファイルやサブディレクトリが存在する場合にはIOExceptionをスローします。 ファイルやサブディレクトリを含めて再帰的に削除したい場合は、二番目の引数&var{recursive};に``true``を指定します。 また、ディレクトリが別のプロセスによって使用されていて削除できない場合にもIOExceptionをスローするので注意が必要です。
+

          
+
#tabpage(codelang=cs,container-title=ディレクトリを削除する)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    try {
+
      // ディレクトリsubdirを削除する
+
      Directory.Delete("subdir");
+
    }
+
    catch (IOException) {
+
      // ディレクトリ内にファイルまたはサブディレクトリがある場合、
+
      // もしくは別のプロセスがディレクトリを使用中の場合はIOExceptionがスローされる
+
    }
+

          
+
    try {
+
      // ディレクトリsubdirとディレクトリ内のすべてのファイル・サブディレクトリを削除する
+
      Directory.Delete("subdir", true);
+
    }
+
    catch (IOException) {
+
      // 別のプロセスがディレクトリを使用中の場合はIOExceptionがスローされる
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Try
+
      ' ディレクトリsubdirを削除する
+
      Directory.Delete("subdir")
+
    Catch ex As IOException
+
      ' ディレクトリ内にファイルまたはサブディレクトリがある場合、
+
      ' もしくは別のプロセスがディレクトリを使用中の場合はIOExceptionがスローされる
+
    End Try
+

          
+
    Try
+
      ' ディレクトリsubdirとディレクトリ内のすべてのファイル・サブディレクトリを削除する
+
      Directory.Delete("subdir", true)
+
    Catch ex As IOException
+
      ' 別のプロセスがディレクトリを使用中の場合はIOExceptionがスローされる
+
    End Try
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+

          
+
**移動・リネーム (Directory.Move) [#Directory.Move]
+
ディレクトリを移動(リネーム)するには&msdn(netfx,member,System.IO.Directory.Move){Moveメソッド};を使用します。
+

          
+
#tabpage(codelang=cs,container-title=ディレクトリを移動する)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // カレントディレクトリにあるsubdir1をtempに移動(リネーム)する
+
    Directory.Move("subdir1", "temp");
+

          
+
    // カレントディレクトリにあるsubdir2をtempディレクトリの下に移動する
+
    Directory.Move("subdir2", @"temp\subdir2");
+

          
+
    // E:\dirをF:\に移動する(異なるボリュームへの移動なのでIOExceptionをスローする)
+
    Directory.Move(@"E:\dir", @"F:\");
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' カレントディレクトリにあるsubdir1をtempに移動(リネーム)する
+
    Directory.Move("subdir1", "temp")
+

          
+
    ' カレントディレクトリにあるsubdir2をtempディレクトリの下に移動する
+
    Directory.Move("subdir2", "temp\subdir2")
+

          
+
    ' E:\dirをF:\に移動する(異なるボリュームへの移動なのでIOExceptionをスローする)
+
    Directory.Move("E:\dir", "F:\")
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
このメソッドでは既に存在するディレクトリ名へのリネームや移動元の子ディレクトリとなるようなディレクトリに移動することはできません。 そういった場合は、ディレクトリ内のファイル・サブディレクトリを個別に移動する必要があります。 また、異なるドライブ(ボリューム)への移動もサポートされません。 この場合は移動先へのコピーを行ったのち、移動元を削除することによって移動する必要があります。
+

          
+
**コピー [#Directory_Copy]
+
Directoryクラスにはディレクトリごと別のディレクトリにコピーするメソッドは用意されていません。 そのため、[[GetFileSystemEntriesなどのメソッド>#Directory.GetFileSystemEntries]]によってディレクトリ内のファイル・サブディレクトリを再帰的に列挙し、1つづつコピーしていく必要があります。
+

          
+
以下のコードは、ディレクトリのコピーを行うメソッドの例です。
+

          
+
#code(cs,ディレクトリをコピーする){{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  /// <summary>ディレクトリ内のファイルおよびサブディレクトリをコピーする</summary>
+
  /// <remarks>このメソッドはディレクトリの属性をコピーしない</remarks>
+
  /// <param name="sourceDirectory">コピー元のディレクトリを表す絶対パスまたは相対パス</param>
+
  /// <param name="destDirectory">コピー先のディレクトリを表す絶対パスまたは相対パス</param>
+
  /// <param name="overwrite">コピー先に同名のファイルが存在する場合に上書きを許可するかどうか</param>
+
  /// <exception cref="IOException"><paramref name="overwrite"/>がfalseの場合、かつコピー先に同名のファイルが存在する</exception>
+
  static void CopyDirectory(string sourceDirectory, string destDirectory, bool overwrite)
+
  {
+
    // 存在しない場合はコピー先ディレクトリを作成する
+
    Directory.CreateDirectory(destDirectory);
+

          
+
    // コピー元のディレクトリにあるファイルをコピーする
+
    foreach (var sourceFile in Directory.EnumerateFiles(sourceDirectory)) {
+
      var destFile = Path.Combine(destDirectory, Path.GetFileName(sourceFile));
+

          
+
      File.Copy(sourceFile, destFile, overwrite);
+
    }
+

          
+
    // 再帰呼び出しによりコピー元のディレクトリにあるサブディレクトリをコピーする
+
    foreach (var sourceSubDirectory in Directory.EnumerateDirectories(sourceDirectory)) {
+
      // サブディレクトリの名前は最後のディレクトリ区切り文字以降の部分となるので、
+
      // Path.GetDirectoryNameではなくPath.GetFileNameを使ってサブディレクトリ名を取得する
+
      var destSubDirectory = Path.Combine(destDirectory, Path.GetFileName(sourceSubDirectory));
+

          
+
      CopyDirectory(sourceSubDirectory, destSubDirectory, overwrite);
+
    }
+
  }
+

          
+
  static void Main()
+
  {
+
    // カレントディレクトリにあるdirディレクトリをコピーして_backupディレクトリを作成する
+
    CopyDirectory("dir", "_backup", false);
+
  }
+
}
+
}}
+

          
+

          
+

          
+
*ファイルに対する操作 (Fileクラス) [#File]
+
ファイルのコピー・削除・移動などの操作を行うには&msdn(netfx,type,System.IO.File){Fileクラス};のメソッドを使います。
+

          
+
**存在するか調べる (File.Exists) [#File.Exists]
+
ファイルが存在するかどうかを確かめるには&msdn(netfx,member,System.IO.File.Exists){Existsメソッド};を使用します。
+

          
+
#tabpage(codelang=cs,container-title=ファイルが存在するかどうか調べる)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // ファイルE:\dir\file.txtが存在するか調べる
+
    if (File.Exists(@"E:\dir\file.txt"))
+
      Console.WriteLine("ファイルは存在します");
+

          
+
    // カレントディレクトリにファイルfile.txtが存在するか調べる
+
    if (File.Exists("file.txt"))
+
      Console.WriteLine("ファイルは存在します");
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' ファイルE:\dir\file.txtが存在するか調べる
+
    If File.Exists("E:\dir\file.txt") Then
+
      Console.WriteLine("ファイルは存在します")
+
    End If
+

          
+
    ' カレントディレクトリにファイルfile.txtが存在するか調べる
+
    If File.Exists("file.txt") Then
+
      Console.WriteLine("ファイルは存在します")
+
    End If
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+

          
+
**削除 (File.Delete) [#File.Delete]
+
ファイルを削除するには&msdn(netfx,member,System.IO.File.Delete){Deleteメソッド};を使用します。 ファイルが別のプロセスによって使用されていて削除できない場合にはIOExceptionをスローするので注意が必要です。
+

          
+
#tabpage(codelang=cs,container-title=ファイルを削除する)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    try {
+
      // ファイルfile.txtを削除する
+
      File.Delete("file.txt");
+
    }
+
    catch (IOException) {
+
      // 別のプロセスがファイルを使用中の場合はIOExceptionがスローされる
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Try
+
      ' ファイルfile.txtを削除する
+
      File.Delete("file.txt")
+
    Catch ex As IOException
+
      ' 別のプロセスがファイルを使用中の場合はIOExceptionがスローされる
+
    End Try
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+

          
+
**移動・リネーム (File.Move) [#File.Move]
+
ファイルを移動(リネーム)するには&msdn(netfx,member,System.IO.File.Move){Moveメソッド};を使用します。
+

          
+
#tabpage(codelang=cs,container-title=ファイルを移動・リネームする)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // カレントディレクトリにあるfile1.txtをoldfile.txtに移動(リネーム)する
+
    File.Move("file1.txt", "oldfile.txt");
+

          
+
    // カレントディレクトリにあるfile2.txtをディレクトリE:\dir\に移動する
+
    File.Move("file2.txt", @"E:\dir\");
+

          
+
    // カレントディレクトリにあるfile2.txtをディレクトリsubdirに移動し、
+
    // ファイル名をfile.txtにリネームする
+
    Directory.CreateDirectory("subdir"); // 事前に移動先ディレクトリを作成しておく
+

          
+
    File.Move("file3.txt", @"subdir\file.txt");
+
  }
+
}
+

          
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' カレントディレクトリにあるfile1.txtをoldfile.txtに移動(リネーム)する
+
    File.Move("file1.txt", "oldfile.txt")
+

          
+
    ' カレントディレクトリにあるfile2.txtをディレクトリE:\dir\に移動する
+
    File.Move("file2.txt", "E:\dir\")
+

          
+
    ' カレントディレクトリにあるfile2.txtをディレクトリsubdirに移動し、
+
    ' ファイル名をfile.txtにリネームする
+
    Directory.CreateDirectory("subdir") ' 事前に移動先ディレクトリを作成しておく
+

          
+
    File.Move("file3.txt", "subdir\file.txt")
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
このメソッドでは既に存在するファイル名へリネームすることはできません。 したがって、Moveメソッドによるファイルのリネームではファイルの上書きが行われることはありません。 存在するファイル名へのリネームを行おうとした場合にはIOExceptionがスローされます。 また、移動先のディレクトリが存在しない場合にはDirectoryNotFoundExceptionがスローされるため、事前に移動先の[[ディレクトリを作成>#Directory.CreateDirectory]]しておく必要があります。
+

          
+

          
+
**ファイルのコピー (File.Copy) [#File.Copy]
+
ファイルをコピーするには&msdn(netfx,member,System.IO.File.Copy){Copyメソッド};を使用します。 三番目の引数&var{overwrite};に``true``を指定するとコピー先のファイルが存在する場合に上書きを許可します。 指定しなかった場合、もしくは``false``を指定した場合では、コピー先のファイルが存在する場合にはIOExceptionがスローされます。
+

          
+
#tabpage(codelang=cs,container-title=ファイルをコピーする)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // カレントディレクトリにあるfile.txtをディレクトリbackup内のfile.bakにコピーする
+
    Directory.CreateDirectory("backup"); // 事前にコピー先ディレクトリを作成しておく
+

          
+
    File.Copy("file.txt", @"backup\file.bak");
+

          
+
    // カレントディレクトリにあるfile.txtをoldfile.txtというファイル名でコピーする
+
    // コピー先のファイルが存在する場合は上書きする
+
    File.Copy("file.txt", "oldfile.txt", true);
+

          
+
    try {
+
      // カレントディレクトリにあるfile.txtをoldfile.txtというファイル名でコピーする
+
      // コピー先のファイルが存在しても上書きを許可しない
+
      File.Copy("file.txt", "oldfile.txt", false);
+
    }
+
    catch (IOException) {
+
      // 既にoldfile.txtが存在するのでIOExceptionがスローされる
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' カレントディレクトリにあるfile.txtをディレクトリbackup内のfile.bakにコピーする
+
    Directory.CreateDirectory("backup") ' 事前にコピー先ディレクトリを作成しておく
+

          
+
    File.Copy("file.txt", "backup\file.bak")
+

          
+
    ' カレントディレクトリにあるfile.txtをoldfile.txtというファイル名でコピーする
+
    ' コピー先のファイルが存在する場合は上書きする
+
    File.Copy("file.txt", "oldfile.txt", true)
+

          
+
    Try
+
      ' カレントディレクトリにあるfile.txtをoldfile.txtというファイル名でコピーする
+
      ' コピー先のファイルが存在しても上書きを許可しない
+
      File.Copy("file.txt", "oldfile.txt", false)
+
    Catch ex As IOException
+
      ' 既にoldfile.txtが存在するのでIOExceptionがスローされる
+
    End Try
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
[[Moveメソッド>#File.Move]]と同様、コピー先のディレクトリが存在しない場合にはDirectoryNotFoundExceptionがスローされるため、事前にコピー先の[[ディレクトリを作成>#Directory.CreateDirectory]]しておく必要があります。
+

          
+

          
+
**ファイルの作成・オープン (File.Create, File.Open) [#File.Open]
+
Fileクラスには既存のファイルを開く&msdn(netfx,member,System.IO.File.Open){Openメソッド};や、新しくファイルを作成または上書きして開く&msdn(netfx,member,System.IO.File.Create){Createメソッド};が用意されています。
+

          
+
#tabpage(codelang=cs,container-title=ファイルを作成して文字列を書き込む)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // ファイルfile.txtを作成して開く
+
    using (FileStream stream = File.Create("file.txt")) {
+
      // FileStreamに書き込むためのStreamWriterを作成
+
      using (StreamWriter writer = new StreamWriter(stream)) {
+
        // 文字列を改行付きで書き込む
+
        writer.WriteLine("Hello, world!");
+
      }
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' ファイルfile.txtを作成して開く
+
    Using stream As FileStream = File.Create("file.txt")
+
      ' FileStreamに書き込むためのStreamWriterを作成
+
      Using writer As New StreamWriter(stream)
+
        ' 文字列を改行付きで書き込む
+
        writer.WriteLine("Hello, world!")
+
      End Using
+
    End Using
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
開いたファイルへの読み書きは、Createメソッド・Openメソッドが返す&msdn(netfx,type,System.IO.FileStream){FileStream};を使って行います。 これらのメソッドとFileStreamについては[[programming/netfx/stream/1_1_filestream]]で解説しています。
+

          
+
また、開いたファイルを使ってテキストを読み書きする方法については[[programming/netfx/stream/2_streamreader_streamwriter]]、バイナリの読み書きを行う方法については[[programming/netfx/stream/3_binaryreader_binarywriter]]で解説しています。
+

          
+

          
+
**ファイル属性 [#file_attribute]
+
&msdn(netfx,member,System.IO.File.GetAttributes){GetAttributes};・&msdn(netfx,member,System.IO.File.SetAttributes){SetAttributes};メソッドを使うことでファイル属性の取得・設定を行うことができます。 このメソッドでは、属性をブール型や整数型ではなく&msdn(netfx,type,System.IO.FileAttributes){FileAttributes列挙体};のビットごとの組み合わせによって表現します。
+

          
+
#tabpage(codelang=cs,container-title=ファイルの属性を取得・設定する)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // file.txtのファイル属性を取得する
+
    FileAttributes attr = File.GetAttributes("file.txt");
+

          
+
    // ファイル属性に読み取り専用属性を追加する
+
    attr = attr | FileAttributes.ReadOnly;
+

          
+
    // 変更したファイル属性をfile.txtに設定する
+
    File.SetAttributes("file.txt", attr);
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' file.txtのファイル属性を取得する
+
    Dim attr As FileAttributes = File.GetAttributes("file.txt")
+

          
+
    ' ファイル属性に読み取り専用属性を追加する
+
    attr = attr Or FileAttributes.ReadOnly
+

          
+
    ' 変更したファイル属性をfile.txtに設定する
+
    File.SetAttributes("file.txt", attr)
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
列挙体とビットごとの組み合わせについては[[programming/netfx/enum/1_flags]]や[[programming/netfx/enum/0_enum#Enum.HasFlags]]を参照してください。
+

          
+
Monoの場合、非Windows環境では読み取り専用の属性のみがエミュレートされ、それ以外の属性は無視されます。 ファイルパーミッションの変更を行いたい場合は、Mono.Unix.UnixFileInfoクラスのProtectionプロパティを使う必要があります。
+

          
+

          
+
**タイムスタンプ [#file_timestamp]
+
Fileクラスにはファイルのタイムスタンプを扱う以下のようなメソッドが用意されています。 ファイルだけでなくディレクトリのタイムスタンプを取得・設定する場合もこれらのメソッドを使うことができます。 同名のメソッドはDirectoryクラスにも用意されていて、同じくディレクトリだけでなくファイルのタイムスタンプを取得・設定できるようになっています。
+

          
+
|*Fileクラスのタイムスタンプを扱うメソッド
+
|~タイムスタンプの種類|~取得用のメソッド|~設定用のメソッド|h
+
|~作成日時|&msdn(netfx,member,System.IO.File.GetCreationTime){GetCreationTime};&br;&msdn(netfx,member,System.IO.File.GetCreationTimeUtc){GetCreationTimeUtc};|&msdn(netfx,member,System.IO.File.SetCreationTime){SetCreationTime};&br;&msdn(netfx,member,System.IO.File.SetCreationTimeUtc){SetCreationTimeUtc};|
+
|~書き込み日時|&msdn(netfx,member,System.IO.File.GetLastWriteTime){GetLastWriteTime};&br;&msdn(netfx,member,System.IO.File.GetLastWriteTimeUtc){GetLastWriteTimeUtc};|&msdn(netfx,member,System.IO.File.SetLastWriteTime){SetLastWriteTime};&br;&msdn(netfx,member,System.IO.File.SetLastWriteTimeUtc){SetLastWriteTimeUtc};|
+
|~アクセス日時|&msdn(netfx,member,System.IO.File.GetLastAccessTime){GetLastAccessTime};&br;&msdn(netfx,member,System.IO.File.GetLastAccessTimeUtc){GetLastAccessTimeUtc};|&msdn(netfx,member,System.IO.File.SetLastAccessTime){SetLastAccessTime};&br;&msdn(netfx,member,System.IO.File.SetLastAccessTimeUtc){SetLastAccessTimeUtc};|
+

          
+
#tabpage(codelang=cs,container-title=ファイルのタイムスタンプを取得する)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // file.txtのタイムスタンプを取得する
+
    DateTime creation = File.GetCreationTime("file.txt");
+
    DateTime lastWrite = File.GetLastWriteTime("file.txt");
+
    DateTime lastAccess = File.GetLastAccessTime("file.txt");
+

          
+
    Console.WriteLine(creation);
+
    Console.WriteLine(lastWrite);
+
    Console.WriteLine(lastAccess);
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' file.txtのタイムスタンプを取得する
+
    Dim creation As DateTime = File.GetCreationTime("file.txt")
+
    Dim lastWrite As DateTime = File.GetLastWriteTime("file.txt")
+
    Dim lastAccess As DateTime = File.GetLastAccessTime("file.txt")
+

          
+
    Console.WriteLine(creation)
+
    Console.WriteLine(lastWrite)
+
    Console.WriteLine(lastAccess)
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
これらのメソッドではタイムスタンプを[[DateTime型>programming/netfx/datetime/0_abstract#DateTime]]で扱います。 タイムスタンプを整数値に変換したい場合は[[DateTime.ToFileTimeメソッド>programming/netfx/datetime/0_abstract#DateTime_ToFileTimeFromFileTime]]を使います。 また、UNIX時間に変換する方法については[[programming/netfx/tips/convert_unixtime_into_datetime]]で解説しています。
+

          
+
末尾に〜UtcとついているメソッドではタイムスタンプをUTCでの日時で扱い、それ以外のメソッドではローカル時刻で扱います。 ローカル時刻・UTCについては[[programming/netfx/datetime/1_kind_offset_timezone]]を参照してください。
+

          
+

          
+
Monoの場合、UNIX環境ではGet/SetLastAccessTimeはatime(アクセス日時)、Get/SetLastWriteTimeはmtime(変更日時)を取得・設定します。 一方GetCreationTimeはGetLastWriteTimeと同じくmtimeを返しますが、SetCreationTimeの呼び出しでは何もしません。 また、Fileクラスのメソッドでは直接ctime(ステータス変更)の日時を取得・設定することはできません。
+

          
+
#code(cs){{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    File.SetLastAccessTime("file.txt", new DateTime(2000, 1, 1, 0, 0, 0));
+
    File.SetLastWriteTime("file.txt", new DateTime(2000, 1, 2, 0, 0, 0));
+
    File.SetCreationTime("file.txt", new DateTime(2000, 1, 3, 0, 0, 0));
+

          
+
    Console.WriteLine(File.GetLastAccessTime("file.txt"));
+
    Console.WriteLine(File.GetLastWriteTime("file.txt"));
+
    Console.WriteLine(File.GetCreationTime("file.txt"));
+
  }
+
}
+
}}
+

          
+
#prompt(実行結果例){{
+
$ mcs sample.cs && mono sample.exe
+
01/01/2000 00:00:00
+
01/02/2000 00:00:00
+
01/02/2000 00:00:00
+
$ stat file.txt 
+
  File: `file.txt'
+
  Size: 0         	Blocks: 0          IO Block: 4096   通常の空ファイル
+
Device: fc02h/64514d	Inode: 396381      Links: 1
+
Access: (0664/-rw-rw-r--)  Uid: ( 1000/    smdn)   Gid: ( 1000/    smdn)
+
Access: 2000-01-01 00:00:00.000000000 +0900
+
Modify: 2000-01-02 00:00:00.000000000 +0900
+
Change: 2013-11-29 23:19:33.505223150 +0900
+
 Birth: -
+
}}
+

          
+

          
+

          
+
*FileInfo・DirectoryInfo・DriveInfo [#Info_classes]
+
&msdn(netfx,type,System.IO.FileInfo){FileInfoクラス};および&msdn(netfx,type,System.IO.DirectoryInfo){DirectoryInfoクラス};はファイル・ディレクトリを表すクラスです。 [[Fileクラス>#File]]や[[Directoryクラス>#Directory]]を使った操作では常に操作対象となるファイル・ディレクトリのパスを引数に必要としますが、FileInfoクラス・DirectoryInfoクラスではインスタンス自体がファイル・ディレクトリを表し、常にインスタンスがパスを保持していることになり、操作を行う都度パスを指定する必要がなくなります。 Fileクラス・Directoryクラスはインスタンスを作成せずに使用することができますが、FileInfoクラス・DirectoryInfoクラスを使う場合は常にインスタンスを作成する必要があります。
+

          
+
両者の違いを比較するために、FileクラスとFileInfoクラスを使ってファイルの存在確認とコピーを行う例を挙げるとつぎのようになります。
+

          
+
#tabpage(codelang=cs,container-title=FileクラスとFileInfoクラスを使った操作の違い)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // Fileクラスを使ってファイルが存在するか調べる
+
    if (File.Exists("file.txt")) {
+
      Console.WriteLine("file.txtは存在します");
+

          
+
      // file.txtをfile1.txtという名前でコピーする
+
      File.Copy("file.txt", "file1.txt");
+
    }
+

          
+
    // FileInfoクラスを使ってファイルが存在するか調べる
+
    FileInfo f = new FileInfo("file.txt");
+

          
+
    if (f.Exists) {
+
      Console.WriteLine("file.txtは存在します");
+

          
+
      // file.txtをfile2.txtという名前でコピーする
+
      f.CopyTo("file2.txt");
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' Fileクラスを使ってファイルが存在するか調べる
+
    If File.Exists("file.txt") Then
+
      Console.WriteLine("file.txtは存在します")
+

          
+
      ' file.txtをfile1.txtという名前でコピーする
+
      File.Copy("file.txt", "file1.txt")
+
    End If
+

          
+
    ' FileInfoクラスを使ってファイルが存在するか調べる
+
    Dim f As New FileInfo("file.txt")
+

          
+
    If f.Exists Then
+
      Console.WriteLine("file.txtは存在します")
+

          
+
      ' file.txtをfile2.txtという名前でコピーする
+
      f.CopyTo("file2.txt")
+
    End If
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
この例で使用しているExistsメソッドやCopyメソッド以外にも、Fileクラス・Directoryクラスに用意されているファイル・ディレクトリ操作のメソッドはFileInfoクラス・DirectoryInfoクラスにも用意されています。 そのため、どちらのクラスを使っても同じ操作が行えますが、操作を行う際にファイル名・ディレクトリ名を文字列として取り回すか、FileInfo・DirectoryInfoのインスタンスで取り回すかが異なるため、実装の都合に応じて使い分けることができます。
+

          
+
また、ドライブ情報を表す[[DriveInfoクラス>#DriveInfo]]も用意されています。 このクラスを使うと、システムに存在するドライブに関する情報(空き容量やドライブの種類、ルートディレクトリのパス)を取得することができます。 File・Directoryクラスとは異なり、DriveInfoクラスに対応するDriveのようなクラスは存在しないので、ドライブ情報を取得したい場合にはDriveInfoクラスを使う必要があります。
+

          
+
**FileInfoクラス [#FileInfo]
+
&msdn(netfx,type,System.IO.FileInfo){FileInfoクラス};はファイルを表すクラスです。 FileInfoクラスのインスタンスを作成する際はファイル名を含むパスを指定する必要がありますが、相対パス・絶対パスのどちらでも指定することもできます。 また、存在しないファイルのインスタンスも作成することができます。
+

          
+
#tabpage(codelang=cs,container-title=FileInfoインスタンスの作成)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // ファイルE:\dir\file.txtを参照するFileInfoのインスタンスを作成する
+
    FileInfo f1 = new FileInfo(@"E:\dir\file.txt");
+

          
+
    // カレントディレクトリにあるファイルfile.txtを参照するFileInfoのインスタンスを作成する
+
    FileInfo f2 = new FileInfo("file.txt");
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' ファイルE:\dir\file.txtを参照するFileInfoのインスタンスを作成する
+
    Dim f1 As New FileInfo("E:\dir\file.txt")
+

          
+
    ' カレントディレクトリにあるファイルfile.txtを参照するFileInfoのインスタンスを作成する
+
    Dim f2 As New FileInfo("file.txt")
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
FileInfoクラスのメソッド・プロパティと[[Fileクラス>#File]]・[[Pathクラス>programming/netfx/filesystem/0_path]]のメソッドの対応は次のとおりです。 FileInfoクラスのメソッド・プロパティの動作は、対応するFileクラス・Pathクラスのメソッドの動作と基本的には同じです。
+

          
+
|*FileInfoクラスのメソッド・プロパティ (抜粋)
+
|~操作|~FileInfoクラスのメンバ|~対応するFileクラス・Pathクラスのメソッド|h
+
|~コピー|&msdn(netfx,member,System.IO.FileInfo.CopyTo){CopyToメソッド};|[[File.Copy>#File.Copy]]|
+
|~移動・リネーム|&msdn(netfx,member,System.IO.FileInfo.MoveTo){MoveToメソッド};|[[File.Move>#File.Move]]|
+
|~削除|&msdn(netfx,member,System.IO.FileInfo.Delete){Deleteメソッド};|[[File.Delete>#File.Delete]]|
+
|~ファイルが存在するか|&msdn(netfx,member,System.IO.FileInfo.Exists){Existsプロパティ};|[[File.Exists>#File.Exists]]|
+
|~ファイルの作成|&msdn(netfx,member,System.IO.FileInfo.Create){Createメソッド};|[[File.Create>#File.Open]]|
+
|~ファイルのオープン|&msdn(netfx,member,System.IO.FileInfo.Open){Open};/&msdn(netfx,member,System.IO.FileInfo.OpenRead){OpenRead};/&msdn(netfx,member,System.IO.FileInfo.OpenWrite){OpenWrite};メソッド|[[File.Open/OpenRead/OpenWrite>#File.Open]]|
+
|~フルパスの取得|&msdn(netfx,member,System.IO.FileInfo.FullName){FullNameプロパティ};|[[Path.GetFullPath>programming/netfx/filesystem/0_path#Path.GetFullPath]]|
+
|~ディレクトリ名の取得|&msdn(netfx,member,System.IO.FileInfo.DirectoryName){DirectoryNameプロパティ};|[[Path.GetDirectoryName>programming/netfx/filesystem/0_path#Path.GetFileName]]|
+
|~ファイル名の取得|&msdn(netfx,member,System.IO.FileInfo.Name){Nameプロパティ};|[[Path.GetFileName>programming/netfx/filesystem/0_path#Path.GetFileName]]|
+
|~拡張子の取得|&msdn(netfx,member,System.IO.FileInfo.Extension){Extensionプロパティ};|[[Path.GetExtension>programming/netfx/filesystem/0_path#Path.GetExtension]]|
+
|~ファイル属性の取得・設定|&msdn(netfx,member,System.IO.FileInfo.Attributes){Attributesプロパティ};|[[File.GetAttributes/SetAttributes>#file_attribute]]|
+
|~タイムスタンプの取得・設定|{{
+
&msdn(netfx,member,System.IO.FileInfo.CreationTime){CreationTime};/&msdn(netfx,member,System.IO.FileInfo.CreationTimeUtc){CreationTimeUtc};プロパティ
+
&msdn(netfx,member,System.IO.FileInfo.LastAccessTime){LastAccessTime};/&msdn(netfx,member,System.IO.FileInfo.LastAccessTimeUtc){LastAccessTimeUtc};プロパティ
+
&msdn(netfx,member,System.IO.FileInfo.LastWriteTime){LastWriteTime};/&msdn(netfx,member,System.IO.FileInfo.LastWriteTimeUtc){LastWriteTimeUtc};プロパティ
+
}}|[[File.SetCreationTimeなど>#file_timestamp]]|
+
|~ファイルサイズの取得|&msdn(netfx,member,System.IO.FileInfo.Length){Lengthプロパティ};|(なし)|
+
|~操作|~FileInfoクラスのメンバ|~対応するFileクラス・Pathクラスのメソッド|f
+

          
+
DirectoryNameプロパティはディレクトリ名を文字列で取得することができますが、&msdn(netfx,member,System.IO.FileInfo.Directory){Directoryプロパティ};を参照するとファイルが配置されているディレクトリを[[DirectoryInfo>#DirectoryInfo]]で取得することができるようになっています。
+

          
+
**DirectoryInfoクラス [#DirectoryInfo]
+
&msdn(netfx,type,System.IO.DirectoryInfo){DirectoryInfoクラス};はディレクトリを表すクラスです。 [[FileInfoクラス>#FileInfo]]と同様にDirectoryInfoクラスのインスタンスを作成する際はディレクトリ名を含むパスを指定する必要がありますが、相対パス・絶対パスのどちらでも指定することもできます。 また、存在しないディレクトリのインスタンスを作成することもできます。
+

          
+
#tabpage(codelang=cs,container-title=DirectoryInfoインスタンスの作成)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // ディレクトリE:\dir\を参照するDirectoryInfoのインスタンスを作成する
+
    DirectoryInfo d1 = new DirectoryInfo(@"E:\dir\");
+

          
+
    // カレントディレクトリにあるディレクトリsubdir1\subdir2を参照するDirectoryInfoのインスタンスを作成する
+
    DirectoryInfo d2 = new DirectoryInfo(@"subdir1\subdir2");
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' ディレクトリE:\dir\を参照するDirectoryInfoのインスタンスを作成する
+
    Dim d1 As New DirectoryInfo("E:\dir\")
+

          
+
    ' カレントディレクトリにあるディレクトリsubdir1\subdir2を参照するDirectoryInfoのインスタンスを作成する
+
    Dim d2 As New DirectoryInfo("subdir1\subdir2")
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
DirectoryInfoクラスのメソッド・プロパティと[[Directoryクラス>#File]]・[[Pathクラス>programming/netfx/filesystem/0_path]]のメソッドの対応は次のとおりです。 DirectoryInfoクラスのメソッド・プロパティの動作は、対応するDirectoryクラス・Pathクラスのメソッドの動作と基本的には同じです。
+

          
+
|*DirectoryInfoクラスのメソッド・プロパティ (抜粋)
+
|~操作|~DirectoryInfoクラスのメンバ|~対応するDirectoryクラス・Pathクラスのメソッド|h
+
|~作成|&msdn(netfx,member,System.IO.DirectoryInfo.Create){Createメソッド};|[[Directory.CreateDirectory>#Directory.CreateDirectory]]|
+
|~サブディレクトリの作成|&msdn(netfx,member,System.IO.DirectoryInfo.CreateSubdirectory){CreateSubdirectoryメソッド};|[[Directory.CreateDirectory>#Directory.CreateDirectory]]|
+
|~移動・リネーム|&msdn(netfx,member,System.IO.DirectoryInfo.MoveTo){MoveToメソッド};|[[Directory.Move>#Directory.Move]]|
+
|~削除|&msdn(netfx,member,System.IO.DirectoryInfo.Delete){Deleteメソッド};|[[Directory.Delete>#Directory.Delete]]|
+
|~ディレクトリが存在するか|&msdn(netfx,member,System.IO.DirectoryInfo.Exists){Existsプロパティ};|[[Directory.Exists>#Directory.Exists]]|
+
|~フルパスの取得|&msdn(netfx,member,System.IO.DirectoryInfo.FullName){FullNameプロパティ};|[[Path.GetFullPath>programming/netfx/filesystem/0_path#Path.GetFullPath]]|
+
|~ディレクトリ名の取得|&msdn(netfx,member,System.IO.DirectoryInfo.Name){Nameプロパティ};|[[Path.GetDirectoryName>programming/netfx/filesystem/0_path#Path.GetFileName]]|
+
|~タイムスタンプの取得・設定|{{
+
&msdn(netfx,member,System.IO.DirectoryInfo.CreationTime){CreationTime};/&msdn(netfx,member,System.IO.DirectoryInfo.CreationTimeUtc){CreationTimeUtc};プロパティ
+
&msdn(netfx,member,System.IO.DirectoryInfo.LastAccessTime){LastAccessTime};/&msdn(netfx,member,System.IO.DirectoryInfo.LastAccessTimeUtc){LastAccessTimeUtc};プロパティ
+
&msdn(netfx,member,System.IO.DirectoryInfo.LastWriteTime){LastWriteTime};/&msdn(netfx,member,System.IO.DirectoryInfo.LastWriteTimeUtc){LastWriteTimeUtc};プロパティ
+
}}|[[Directory.SetCreationTimeなど>#file_timestamp]]|
+
|~操作|~FileInfoクラスのメンバ|~対応するFileクラス・Pathクラスのメソッド|f
+

          
+
DirectoryInfoクラスでは、親ディレクトリのDirectoryInfoを&msdn(netfx,member,System.IO.DirectoryInfo.Parent){Parentプロパティ};、ルートディレクトリのDirectoryInfoを&msdn(netfx,member,System.IO.DirectoryInfo.Root){Rootプロパティ};でそれぞれ取得することができます。
+

          
+
***DirectoryInfoクラスを使ったディレクトリの走査
+
[[DirectoryクラスのGetFiles・EnumerateFilesメソッド>#Directory.GetFileSystemEntries]]では見つかったファイルの名前が文字列で返されますが、DirectoryInfoクラスの&msdn(netfx,member,System.IO.DirectoryInfo.GetFiles){GetFiles};・&msdn(netfx,member,System.IO.DirectoryInfo.EnumerateFiles){EnumerateFiles};メソッドでは文字列ではなく[[FileInfoクラス>#FileInfo]]が返されます。
+

          
+
#tabpage(codelang=cs,container-title=DirectoryInfoクラスを使ったディレクトリの走査)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // Directoryクラスを使ってディレクトリE:\dirにあるすべてのファイルを取得して列挙する
+
    foreach (string file in Directory.GetFiles(@"E:\dir\")) {
+
      Console.WriteLine(file);
+
    }
+

          
+
    foreach (string file in Directory.EnumerateFiles(@"E:\dir\")) {
+
      Console.WriteLine(file);
+
    }
+

          
+
    // DirectoryInfoクラスを使ってディレクトリE:\dirにあるすべてのファイルを取得して列挙する
+
    DirectoryInfo d = new DirectoryInfo(@"E:\dir\");
+

          
+
    foreach (FileInfo file in d.GetFiles()) {
+
      Console.WriteLine(file.Name);
+
    }
+

          
+
    foreach (FileInfo file in d.EnumerateFiles()) {
+
      Console.WriteLine(file.Name);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' Directoryクラスを使ってディレクトリE:\dirにあるすべてのファイルを取得して列挙する
+
    For Each file As String In Directory.GetFiles("E:\dir\")
+
      Console.WriteLine(file)
+
    Next
+

          
+
    For Each file As String In Directory.EnumerateFiles("E:\dir\")
+
      Console.WriteLine(file)
+
    Next
+

          
+
    ' DirectoryInfoクラスを使ってディレクトリE:\dirにあるすべてのファイルを取得して列挙する
+
    Dim d As New DirectoryInfo("E:\dir\")
+

          
+
    For Each file As FileInfo In d.GetFiles()
+
      Console.WriteLine(file.Name)
+
    Next
+

          
+
    For Each file As FileInfo In d.EnumerateFiles()
+
      Console.WriteLine(file.Name)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
同様にDirectoryInfoクラスの&msdn(netfx,member,System.IO.DirectoryInfo.GetDirectories){GetDirectories};・&msdn(netfx,member,System.IO.DirectoryInfo.EnumerateDirectories){EnumerateDirectories};メソッドでは見つかったディレクトリはDirectoryInfoで返されます。 &msdn(netfx,member,System.IO.DirectoryInfo.GetFileSystemInfos){GetFileSystemInfos};・&msdn(netfx,member,System.IO.DirectoryInfo.EnumerateFileSystemInfos){EnumerateFileSystemInfos};メソッドでは[[FileSystemInfo>#FileSystemInfo]]で返されます。
+

          
+
**FileSystemInfoクラス [#FileSystemInfo]
+
&msdn(netfx,type,System.IO.FileSystemInfo){FileSystemInfoクラス};は&msdn(netfx,member,System.IO.DirectoryInfo.GetFileSystemInfos){GetFileSystemInfos};・&msdn(netfx,member,System.IO.DirectoryInfo.EnumerateFileSystemInfos){EnumerateFileSystemInfos};メソッドの戻り値の型に使用されるクラスです。 このクラスは[[FileInfoクラス>#FileInfo]]および[[DirectoryInfoクラス>#DirectoryInfo]]に共通する基底クラスです。 GetFileSystemInfos・EnumerateFileSystemInfosでは見つかったファイルのFileInfoおよびサブディレクトリのDirectoryInfoが返されます。
+

          
+
#tabpage(codelang=cs,container-title=DirectoryInfo.EnumerateFileSystemInfosメソッドを使ったディレクトリの走査とFileSystemInfoの型チェックの例)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // DirectoryInfo.EnumerateFileSystemInfosメソッドでディレクトリE:\dir直下にある
+
    // すべてのファイルとサブディレクトリを取得して列挙する
+
    DirectoryInfo d = new DirectoryInfo(@"E:\dir\");
+

          
+
    foreach (FileSystemInfo i in d.EnumerateFileSystemInfos()) {
+
      if (i is FileInfo)
+
        Console.WriteLine("{0}はファイルです", i.Name);
+
      else if (i is DirectoryInfo)
+
        Console.WriteLine("{0}はサブディレクトリです", i.Name);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' DirectoryInfo.EnumerateFileSystemInfosメソッドでディレクトリE:\dir直下にある
+
    ' すべてのファイルとサブディレクトリを取得して列挙する
+
    Dim d As New DirectoryInfo("E:\dir\")
+

          
+
    For Each i As FileSystemInfo In d.EnumerateFileSystemInfos()
+
      If TypeOf i Is FileInfo Then
+
        Console.WriteLine("{0}はファイルです", i.Name)
+
      Else If TypeOf i Is DirectoryInfo Then
+
        Console.WriteLine("{0}はサブディレクトリです", i.Name)
+
      End If
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果例){{
+
file1.txtはファイルです
+
file2.txtはファイルです
+
file3.txtはファイルです
+
subdir1はサブディレクトリです
+
subdir2はサブディレクトリです
+
}}
+

          
+
FileSystemInfoクラスにはファイルまたはディレクトリの名前を取得する&msdn(netfx,member,System.IO.FileSystemInfo.Name){Nameプロパティ};、フルパスを取得する&msdn(netfx,member,System.IO.FileSystemInfo.FullName){FullNameプロパティ};、実際に存在するかどうかを取得する&msdn(netfx,member,System.IO.FileSystemInfo.Exists){Existsプロパティ};など[[FileInfoクラス>#FileInfo]]と[[DirectoryInfoクラス>#DirectoryInfo]]に共通するプロパティが用意されています。
+

          
+
**DriveInfoクラス [#DriveInfo]
+
&msdn(netfx,type,System.IO.DriveInfo){DriveInfoクラス};はシステムに存在する論理ドライブの情報を取得するためのクラスです。 コンストラクタでドライブ名を指定してインスタンスを作成するか、&msdn(netfx,member,System.IO.DriveInfo.GetDrives){GetDrivesメソッド};によって存在するすべての論理ドライブのDriveInfoを取得することができます。 &msdn(netfx,member,System.IO.DriveInfo.DriveType){DriveTypeプロパティ};を参照するとドライブの種類(光学ドライブ・固定ディスク・ネットワーク・リムーバブルデバイスなど)を取得することができます。
+

          
+
#tabpage(codelang=cs,container-title=システム上のドライブとドライブ種別の列挙)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // CドライブのDriveInfoを作成する
+
    DriveInfo c = new DriveInfo("C");
+

          
+
    // システムに存在するすべてのドライブを取得する
+
    DriveInfo[] drives = DriveInfo.GetDrives();
+

          
+
    foreach (DriveInfo drive in drives) {
+
      // ドライブ名とドライブの種類を表示する
+
      Console.WriteLine("{0}: {1}", drive.Name, drive.DriveType);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' CドライブのDriveInfoを作成する
+
    Dim c As New DriveInfo("C")
+

          
+
    ' システムに存在するすべてのドライブを取得する
+
    Dim drives() As DriveInfo = DriveInfo.GetDrives()
+

          
+
    For Each drive As DriveInfo In drives
+
      ' ドライブ名とドライブの種類を表示する
+
      Console.WriteLine("{0}: {1}", drive.Name, drive.DriveType)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(Windows上の.NET Frameworkでの実行結果例){{
+
A:\: Removable
+
C:\: Fixed
+
E:\: Fixed
+
F:\: Fixed
+
Q:\: CDRom
+
R:\: CDRom
+
S:\: Network
+
T:\: Network
+
}}
+

          
+
Linux上のMonoではドライブの代わりにマウントされているディレクトリが列挙されます。
+

          
+
#code(cs){{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    foreach (DriveInfo drive in DriveInfo.GetDrives()) {
+
      Console.WriteLine(drive.Name);
+
    }
+
  }
+
}
+
}}
+

          
+
#prompt(Linux上のMonoでの実行結果例){{
+
/
+
/boot
+
/home
+
/srv/www
+
/srv/mail
+
}}
+

          
+
DriveInfoクラスにはこの他にも、ボリュームラベルを取得する&msdn(netfx,member,System.IO.DriveInfo.VolumeLabel){VolumeLabel};、ファイルシステムの種類(NTFSなど)を文字列形式で返す&msdn(netfx,member,System.IO.DriveInfo.DriveFormat){DriveFormat};、ドライブの容量を取得する&msdn(netfx,member,System.IO.DriveInfo.TotalSize){TotalSize};, &msdn(netfx,member,System.IO.DriveInfo.TotalFreeSpace){TotalFreeSpace};, &msdn(netfx,member,System.IO.DriveInfo.AvailableFreeSpace){AvailableFreeSpace};などのプロパティがありますが、これらの値はいずれもドライブの準備ができていない場合(CDが挿入されていないなど)に取得しようとするとIOExceptionをスローします。 メディアが使用可能か・ドライブの準備ができているかを調べるには&msdn(netfx,member,System.IO.DriveInfo.IsReady){IsReadyプロパティ};を参照します。
+

          
+
#tabpage(codelang=cs,container-title=ドライブの列挙とドライブ情報の取得)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // システムに存在するすべてのドライブを取得する
+
    DriveInfo[] drives = DriveInfo.GetDrives();
+

          
+
    foreach (DriveInfo drive in drives) {
+
      // ドライブ名とドライブの種類を表示する
+
      Console.Write("{0}: {1}", drive.Name, drive.DriveType);
+

          
+
      if (drive.IsReady)
+
        // ドライブが使用可能な場合は、ドライブの情報を取得する
+
        Console.WriteLine(" ({0}, {1:N0} bytes)", drive.DriveFormat, drive.TotalSize);
+
      else
+
        Console.WriteLine();
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' システムに存在するすべてのドライブを取得する
+
    Dim drives() As DriveInfo = DriveInfo.GetDrives()
+

          
+
    For Each drive As DriveInfo In drives
+
      ' ドライブ名とドライブの種類を表示する
+
      Console.Write("{0}: {1}", drive.Name, drive.DriveType)
+

          
+
      If drive.IsReady Then
+
        ' ドライブが使用可能な場合は、ドライブの情報を取得する
+
        Console.WriteLine(" ({0}, {1:N0} bytes)", drive.DriveFormat, drive.TotalSize)
+
      Else
+
        Console.WriteLine()
+
      End If
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(Windows上の.NET Frameworkでの実行結果例){{
+
A:\: Removable
+
C:\: Fixed (NTFS, 80,024,170,496 bytes)
+
E:\: Fixed (NTFS, 81,961,938,944 bytes)
+
F:\: Fixed (NTFS, 1,000,202,039,296 bytes)
+
Q:\: CDRom
+
R:\: CDRom
+
S:\: Network (NTFS, 147,640,692,736 bytes)
+
T:\: Network (NTFS, 499,962,740,736 bytes)
+
}}
+

          
+
#prompt(Linux上のMonoでの実行結果例){{
+
/: Fixed (ext, 21,137,846,272 bytes)
+
/boot: Fixed (ext, 1,059,500,032 bytes)
+
/home: Fixed (ext, 10,568,916,992 bytes)
+
/srv/www: Fixed (ext, 98,430,779,392 bytes)
+
/srv/mail: Fixed (ext, 98,430,779,392 bytes)
+
}}
+

          
+
DriveInfoクラスには光学ドライブのトレー開閉、メディアの取り外し・接続を行ったりするような操作を行うメソッドは用意されていません。 そういった操作を行う例は[[programming/netfx/tips/eject_cdrom]]で紹介しています。
+

          
+

          
+

          
+
#navi(..)
+

          

programming/netfx/filesystem/index.wiki.txt

current previous
1,9 0,0
+
${smdncms:title,ファイルシステム}
+
${smdncms:keywords,System.IO,ファイルシステム}
+

          
+
ここでは.NET Frameworkにおけるファイル・ディレクトリなどファイルシステムの操作と&msdn(netfx,ns,System.IO){System.IO名前空間};のクラスについて見ていきます。
+

          
+
#googleadunit(banner)
+

          
+
#dir_toc
+

          

programming/netfx/filesystem/0_path/index.wiki.txt

current previous
1,984 0,0
+
${smdncms:title,パスの操作}
+
${smdncms:header_title,パスの操作 (System.IO.Path)}
+
${smdncms:keywords,Path,パス,結合,分解,ファイル,ディレクトリ}
+
${smdncms:document_versions,codelang=cs,codelang=vb}
+

          
+
#navi(..)
+

          
+
パスからファイル名・ディレクトリ名を抽出したり、パスを結合したりするには&msdn(netfx,type,System.IO.Path){Pathクラス};を使います。 単純な文字列操作でもパスの抽出・結合といった操作を行うことはできますが、Pathクラスに用意されているメソッドには次のようなメリットがあります。
+

          
+
+相対パス(``.``や``..``など)の扱いやパスが正しく区切り文字で終わっているかとどうかといった細かい考慮が不要
+
+通常のパス(例:``C:\Windows\Microsoft.NET\``)だけでなく、ドライブ名を省略したパス(例:``\Windows\Microsoft.NET\``)、UNCパス(例:``\\SERV1\dir\``)などがサポートされている
+
+自動的に適切なディレクトリ区切り文字が使われるので、LinuxやMac環境でもパス区切り文字の違い(``\``と``/``)を意識しなければならない個所が減る (Monoなどを使った場合)
+

          
+
このように、特殊な場合を除けばPathクラスのメソッドを使わずわざわざ文字列操作によってパスの処理を記述するメリットはありません。 Pathクラスではインスタンスを作成する必要はありません。 Pathクラスでパスの操作を行う場合は常にクラスメソッドを呼び出して行います。
+

          
+
なお、ここでは''フォルダ''という用語は使わずクラス名にも使われている''ディレクトリ''で統一します。
+

          
+
-関連するページ
+
--[[programming/netfx/environment/0_platform#SystemAndPlatform_DirectorySeparatorChar]]
+
--[[programming/netfx/environment/0_platform#SystemAndPlatform_SpecialDirectory]]
+
--[[programming/netfx/environment/1_process#ProcessAndAssembly_CurrentDirectory]]
+
--[[programming/netfx/environment/1_process#ProcessAndAssembly_ProcessFilePath]]
+

          
+
#googleadunit
+

          
+
本文中のサンプルではパスを記述するために[[逐語的文字列リテラル>programming/netfx/basic_types/1_literal_suffix#VerbatimStringLiterals]]を使用している個所があります。 C#では文字列中の``\``はエスケープ記号として扱われるため、ディレクトリ区切り文字を記述するには``\\``のように二つ重ねる必要がありますが、アットマーク``@``を前置して逐語的文字列リテラルとして記述する場合は、``\``はエスケープ記号としては扱われなくなり、ディレクトリ区切り文字はそのまま``\``と記述できるようになるためパスが読みやすくなります。
+

          
+
#code(cs,パスと逐語的文字列リテラルの例){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 通常の文字列リテラルを使って記述したパス
+
    string path1 = "C:\\Windows\\Microsoft.NET\\Framework";
+
    // 逐語的文字列リテラルを使って記述したパス
+
    string path2 = @"C:\Windows\Microsoft.NET\Framework";
+

          
+
    // path1とpath2はどちらも同じ文字列となる
+
    Console.WriteLine(path1);
+
    Console.WriteLine(path2);
+
  }
+
}
+
}}
+

          
+
#prompt(実行結果){{
+
C:\Windows\Microsoft.NET\Framework
+
C:\Windows\Microsoft.NET\Framework
+
}}
+

          
+
*パスの分割
+
ここではPathクラスのメソッドを使ってパスからファイル名や拡張子などを取得する方法について解説します。
+

          
+
**ファイル名・ディレクトリ名 [#Path.GetFileName]
+
パスからファイル名を抽出するには&msdn(netfx,member,System.IO.Path.GetFileName){GetFileNameメソッド};、ディレクトリ名を抽出するには&msdn(netfx,member,System.IO.Path.GetDirectoryName){GetDirectoryNameメソッド};を使います。 GetDirectoryNameメソッドでは、パスが絶対パスであればそのディレクトリ部分、相対パスであれば区切り文字(``\``または``/``)以前の部分をディレクトリ名として返します。
+

          
+
#tabpage(codelang=cs,container-title=ファイル名・ディレクトリ名の取得)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    string p1 = @"E:\dir\subdir\file.txt"; // 絶対パス形式
+

          
+
    Console.WriteLine(Path.GetFileName(p1));
+
    Console.WriteLine(Path.GetDirectoryName(p1));
+
    Console.WriteLine();
+

          
+
    string p2 = @".\dir\subdir\file.txt"; // 相対パス形式
+

          
+
    Console.WriteLine(Path.GetFileName(p2));
+
    Console.WriteLine(Path.GetDirectoryName(p2));
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim p1 As String = "E:\dir\subdir\file.txt" ' 絶対パス形式
+

          
+
    Console.WriteLine(Path.GetFileName(p1))
+
    Console.WriteLine(Path.GetDirectoryName(p1))
+
    Console.WriteLine()
+

          
+
    Dim p2 As String = ".\dir\subdir\file.txt" ' 相対パス形式
+

          
+
    Console.WriteLine(Path.GetFileName(p2))
+
    Console.WriteLine(Path.GetDirectoryName(p2))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
file.txt
+
E:\dir\subdir
+

          
+
file.txt
+
.\dir\subdir
+
}}
+

          
+
GetFileName・GetDirectoryNameメソッドはパスが実際にファイルであるか、ディレクトリであるかは検証しません。 そのため、次の例のようにディレクトリ区切り文字で終わっていないパスは、それがディレクトリを表すものであってもファイル名として扱われる点に注意が必要です。
+

          
+
#tabpage(codelang=cs,container-title=サブディレクトリ名の取得)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // ディレクトリを表すパス (ディレクトリ区切り文字で終わっていない場合)
+
    string path1 = @"dir\subdir";
+

          
+
    Console.WriteLine("path = {0}", path1);
+
    Console.WriteLine("directory = {0}", Path.GetDirectoryName(path1));
+
    Console.WriteLine("file = {0}", Path.GetFileName(path1));
+
    Console.WriteLine();
+

          
+
    // ディレクトリを表すパス (ディレクトリ区切り文字で終わっている場合)
+
    string path2 = @"dir\subdir\";
+

          
+
    Console.WriteLine("path = {0}", path2);
+
    Console.WriteLine("directory = {0}", Path.GetDirectoryName(path2));
+
    Console.WriteLine("file = {0}", Path.GetFileName(path2));
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' ディレクトリを表すパス (ディレクトリ区切り文字で終わっていない場合)
+
    Dim path1 As String = "dir\subdir"
+

          
+
    Console.WriteLine("path = {0}", path1)
+
    Console.WriteLine("directory = {0}", Path.GetDirectoryName(path1))
+
    Console.WriteLine("file = {0}", Path.GetFileName(path1))
+
    Console.WriteLine()
+

          
+
    ' ディレクトリを表すパス (ディレクトリ区切り文字で終わっている場合)
+
    Dim path2 As String = "dir\subdir\"
+

          
+
    Console.WriteLine("path = {0}", path2)
+
    Console.WriteLine("directory = {0}", Path.GetDirectoryName(path2))
+
    Console.WriteLine("file = {0}", Path.GetFileName(path2))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
path = dir\subdir
+
directory = dir
+
file = subdir
+

          
+
path = dir\subdir\
+
directory = dir\subdir
+
file = 
+
}}
+

          
+
拡張子を除いたファイル名が必要な場合は&msdn(netfx,member,System.IO.Path.GetFileNameWithoutExtension){GetFileNameWithoutExtensionメソッド};を使います。 拡張子がなければファイル名がそのまま返されます。
+

          
+
#tabpage(codelang=cs,container-title=拡張子を除いたファイル名の取得)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    string p1 = @"E:\dir\subdir\file.txt";
+

          
+
    Console.WriteLine(Path.GetFileName(p1));
+
    Console.WriteLine(Path.GetFileNameWithoutExtension(p1));
+
    Console.WriteLine();
+

          
+
    string p2 = @"dir\file";
+

          
+
    Console.WriteLine(Path.GetFileName(p2));
+
    Console.WriteLine(Path.GetFileNameWithoutExtension(p2));
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim p1 As String = "E:\dir\subdir\file.txt"
+

          
+
    Console.WriteLine(Path.GetFileName(p1))
+
    Console.WriteLine(Path.GetFileNameWithoutExtension(p1))
+
    Console.WriteLine()
+

          
+
    Dim p2 As String = "dir\file"
+

          
+
    Console.WriteLine(Path.GetFileName(p2))
+
    Console.WriteLine(Path.GetFileNameWithoutExtension(p2))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
file.txt
+
file
+

          
+
file
+
file
+
}}
+

          
+
ドライブ名だけを返すメソッドは用意されていませんが、[[GetPathRootメソッド>#Path.GetPathRoot]]でパスからルートディレクトリを取得できるので、これを使うことでドライブ名を取得することができます。 ルートディレクトリを含まない相対パスの場合は、空の文字列が返されます。
+

          
+
#tabpage(codelang=cs,container-title=ドライブ名の取得)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    string path1 = @"E:\dir\subdir\file.txt"; // 絶対パス形式
+

          
+
    Console.WriteLine(Path.GetPathRoot(path1));
+

          
+
    string path2 = @"dir\file.txt"; // 相対パス形式
+

          
+
    Console.WriteLine(Path.GetPathRoot(path2));
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim path1 As String = "E:\dir\subdir\file.txt" ' 絶対パス形式
+

          
+
    Console.WriteLine(Path.GetPathRoot(path1))
+

          
+
    Dim path2 As String = "dir\file.txt" ' 相対パス形式
+

          
+
    Console.WriteLine(Path.GetPathRoot(path2))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
E:\
+

          
+
}}
+

          
+
**拡張子 [#Path.GetExtension]
+
パスまたはファイル名から拡張子を抽出するには&msdn(netfx,member,System.IO.Path.GetExtension){GetExtensionメソッド};を使います。 このメソッドではピリオド``.``も含めて拡張子として扱われます(ファイル名が``file.txt``なら拡張子は``.txt``となる)。 拡張子がないファイル名の場合は空の文字列が返されます。 ピリオドが複数あるファイル名の場合は、一番最後のピリオド以降を拡張子として返します。
+

          
+
#tabpage(codelang=cs,container-title=拡張子の取得)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    Console.WriteLine(Path.GetExtension(@"E:\dir\subdir\file.txt"));
+
    Console.WriteLine(Path.GetExtension(@"dir\file.txt"));
+
    Console.WriteLine(Path.GetExtension(@"dir\file")); // 拡張子を持たないファイル名
+
    Console.WriteLine(Path.GetExtension(@"file.txt.bak")); // ピリオドを二つ以上含むファイル名
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Console.WriteLine(Path.GetExtension("E:\dir\subdir\file.txt"))
+
    Console.WriteLine(Path.GetExtension("dir\file.txt"))
+
    Console.WriteLine(Path.GetExtension("dir\file")) ' 拡張子を持たないファイル名
+
    Console.WriteLine(Path.GetExtension("file.txt.bak")) ' ピリオドを二つ以上含むファイル名
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
.txt
+
.txt
+

          
+
.bak
+
}}
+

          
+
パスが拡張子を持つかどうかを調べるには&msdn(netfx,member,System.IO.Path.HasExtension){HasExtensionメソッド};を使います。
+

          
+
#tabpage(codelang=cs,container-title=パスが拡張子を持つかどうかを調べる)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    string[] paths = new[] {
+
      @"E:\dir\subdir\file.txt",
+
      @"E:\dir\subdir\file",
+
      @"file.txt.bak",
+
      @"file",
+
    };
+

          
+
    foreach (string p in paths) {
+
      Console.WriteLine("HasExtension(\"{0}\") = {1}", p, Path.HasExtension(p));
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim paths() As String = New String() { _
+
      "E:\dir\subdir\file.txt", _
+
      "E:\dir\subdir\file", _
+
      "file.txt.bak", _
+
      "file" _
+
    }
+

          
+
    For Each p As String In paths
+
      Console.WriteLine("HasExtension(""{0}"") = {1}", p, Path.HasExtension(p))
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
HasExtension("E:\dir\subdir\file.txt") = True
+
HasExtension("E:\dir\subdir\file") = False
+
HasExtension("file.txt.bak") = True
+
HasExtension("file") = False
+
}}
+

          
+
パスまたはファイル名の拡張子を別の拡張子に置き換えるには&msdn(netfx,member,System.IO.Path.ChangeExtension){ChangeExtensionメソッド};を使います。 元のパス・ファイル名に拡張子がない場合は拡張子が追加され、ピリオドが二つ以上あるファイル名の場合は一番最後のピリオド以降が置き換えられます。
+

          
+
#tabpage(codelang=cs,container-title=パス内に含まれる拡張子を置き換える)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    string[] paths = new[] {
+
      @"E:\dir\subdir\file.txt",
+
      @"E:\dir\subdir\file.txt.bak",
+
      @"E:\dir\subdir\file.bmp",
+
      @"E:\dir\subdir\file",
+
      @"file.txt",
+
      @"file.txt.bak",
+
      @"file",
+
    };
+

          
+
    foreach (string p in paths) {
+
      // パス中の拡張子を.datに置き換える
+
      Console.WriteLine(Path.ChangeExtension(p, ".dat"));
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim paths() As String = New String() { _
+
      "E:\dir\subdir\file.txt", _
+
      "E:\dir\subdir\file.txt.bak", _
+
      "E:\dir\subdir\file.bmp", _
+
      "E:\dir\subdir\file", _
+
      "file.txt", _
+
      "file.txt.bak", _
+
      "file" _
+
    }
+

          
+
    For Each p As String In paths
+
      ' パス中の拡張子を.datに置き換える
+
      Console.WriteLine(Path.ChangeExtension(p, ".dat"))
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
E:\dir\subdir\file.dat
+
E:\dir\subdir\file.txt.dat
+
E:\dir\subdir\file.dat
+
E:\dir\subdir\file.dat
+
file.dat
+
file.txt.dat
+
file.dat
+
}}
+

          
+
置き換える拡張子に空の文字列を指定した場合、ピリオドだけの拡張子に置き換えられます。 一方、``null/Nothing``を指定した場合は、ピリオドも含めて拡張子が削除されます。
+

          
+
#tabpage(codelang=cs,container-title=パス内に含まれる拡張子を削除する)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    string file = "file.txt";
+

          
+
    Console.WriteLine(Path.ChangeExtension(file, ".dat")); // 拡張子を.datに置き換える
+
    Console.WriteLine(Path.ChangeExtension(file, string.Empty)); // ピリオドを残して拡張子を削除する
+
    Console.WriteLine(Path.ChangeExtension(file, null)); // ピリオドも含めて拡張子を削除する
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim file As String = "file.txt"
+

          
+
    Console.WriteLine(Path.ChangeExtension(file, ".dat")) ' 拡張子を.datに置き換える
+
    Console.WriteLine(Path.ChangeExtension(file, String.Empty)) ' ピリオドを残して拡張子を削除する
+
    Console.WriteLine(Path.ChangeExtension(file, Nothing)) ' ピリオドも含めて拡張子を削除する
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
file.dat
+
file.
+
file
+
}}
+

          
+
ChangeExtensionメソッドが用意されている一方、Pathクラスには拡張子を除くファイル名部分だけを置き換えるChangeFileNameといったメソッドは用意されていないので、GetExtensionメソッドなどを組み合わせて実装する必要があります。
+

          
+
#tabpage(codelang=cs,container-title=パス内に含まれるファイル名を置き換える例)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  // パスの拡張子を除いたファイル名部分だけを置き換えるメソッド
+
  static string ChangeFileName(string path, string newFileName)
+
  {
+
    string dir = Path.GetDirectoryName(path); // ディレクトリ部分を抽出
+
    string ext = Path.GetExtension(path); // 拡張子部分を抽出
+

          
+
    // ディレクトリ、新しいファイル名、拡張子を連結して返す
+
    return Path.Combine(dir, newFileName + ext);
+
  }
+

          
+
  static void Main()
+
  {
+
    Console.WriteLine(ChangeFileName(@"E:\dir\subdir\file.txt", "ファイル"));
+
    Console.WriteLine(ChangeFileName(@"E:\dir\subdir\file", "ファイル"));
+
    Console.WriteLine(ChangeFileName(@"image.bmp", "画像"));
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  ' パスの拡張子を除いたファイル名部分だけを置き換えるメソッド
+
  Shared Function ChangeFileName(ByVal p As String, ByVal newFileName As String) As String
+
    Dim dir As String = Path.GetDirectoryName(p) ' ディレクトリ部分を抽出
+
    Dim ext As String = Path.GetExtension(p) ' 拡張子部分を抽出
+

          
+
    ' ディレクトリ、新しいファイル名、拡張子を連結して返す
+
    Return Path.Combine(dir, newFileName + ext)
+
  End Function
+

          
+
  Shared Sub Main()
+
    Console.WriteLine(ChangeFileName("E:\dir\subdir\file.txt", "ファイル"))
+
    Console.WriteLine(ChangeFileName("E:\dir\subdir\file", "ファイル"))
+
    Console.WriteLine(ChangeFileName("image.bmp", "画像"))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
E:\dir\subdir\ファイル.txt
+
E:\dir\subdir\ファイル
+
画像.bmp
+
}}
+

          
+
*パスの結合 [#Path.Combine]
+
パスを結合するには&msdn(netfx,member,System.IO.Path.Combine){Combineメソッド};を使います。 このメソッドを使うことで、部分に分割されているパスを単一のパスに結合することができます。 パスは相対パス同士でも結合することができ、区切り文字で終わっていないパスの場合は区切り文字を追加した上で結合されます。 また、このメソッドでは``.``や``..``は正規化されずそのまま結合されます。
+

          
+
#tabpage(codelang=cs,container-title=パスの結合)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 絶対パスのディレクトリとファイル名を結合する
+
    Console.WriteLine(Path.Combine(@"E:\dir\", @"file.txt"));
+

          
+
    // 区切り文字で終わっていない絶対パスとファイル名を結合する
+
    Console.WriteLine(Path.Combine(@"E:\dir", @"file.txt"));
+

          
+
    // 絶対パスのディレクトリと相対パスを結合する
+
    Console.WriteLine(Path.Combine(@"E:\dir\", @"subdir\file.txt"));
+

          
+
    // ".."(親ディレクトリ)を含む相対パスを結合する
+
    Console.WriteLine(Path.Combine(@"E:\dir\", @"..\file.txt"));
+

          
+
    // 相対パス同士を結合する
+
    Console.WriteLine(Path.Combine(@"dir\subdir", @".\file.txt"));
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 絶対パスのディレクトリとファイル名を結合する
+
    Console.WriteLine(Path.Combine("E:\dir\", "file.txt"))
+

          
+
    ' 区切り文字で終わっていない絶対パスとファイル名を結合する
+
    Console.WriteLine(Path.Combine("E:\dir", "file.txt"))
+

          
+
    ' 絶対パスのディレクトリと相対パスを結合する
+
    Console.WriteLine(Path.Combine("E:\dir\", "subdir\file.txt"))
+

          
+
    ' ".."(親ディレクトリ)を含む相対パスを結合する
+
    Console.WriteLine(Path.Combine("E:\dir\", "..\file.txt"))
+

          
+
    ' 相対パス同士を結合する
+
    Console.WriteLine(Path.Combine("dir\subdir", ".\file.txt"))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
E:\dir\file.txt
+
E:\dir\file.txt
+
E:\dir\subdir\file.txt
+
E:\dir\..\file.txt
+
dir\subdir\.\file.txt
+
}}
+

          
+
``.``や``..``を含むパスの正規化には[[GetFullPathメソッド>#Path.GetFullPath]]を使用します。
+

          
+
Combineメソッドでは自動的に適切なディレクトリ区切り文字が使用されます。 例えば、Windows環境(.NET Framework)では``\``が使われますが、Linux・Mac環境(Mono)では``/``が用いられます。 現在の実行環境でのディレクトリ区切り文字を知りたい場合は&msdn(netfx,member,System.IO.Path.DirectorySeparatorChar){DirectorySeparatorCharプロパティ};を参照します。
+

          
+
#tabpage(codelang=cs,container-title=パスの結合)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // ディレクトリ名とファイル名の結合
+
    Console.WriteLine(Path.Combine("dir", "file.txt"));
+

          
+
    // ディレクトリ区切り文字の取得
+
    Console.WriteLine("DirectorySeparatorChar = {0}", Path.DirectorySeparatorChar);
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' ディレクトリ名とファイル名の結合
+
    Console.WriteLine(Path.Combine("dir", "file.txt"))
+

          
+
    ' ディレクトリ区切り文字の取得
+
    Console.WriteLine("DirectorySeparatorChar = {0}", Path.DirectorySeparatorChar)
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(Windows上の.NET Frameworkでの実行結果){{
+
dir\file.txt
+
DirectorySeparatorChar = \
+
}}
+

          
+
#prompt(Linux上のMonoでの実行結果){{
+
dir/file.txt
+
DirectorySeparatorChar = /
+
}}
+

          
+
Combineメソッドでは最大4つのパスを結合することができます。 それ以上の数の場合でも、配列に格納することでパスを結合することができます。
+

          
+
#tabpage(codelang=cs,container-title=パスの結合)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    Console.WriteLine(Path.Combine("dir", "file.txt"));
+
    Console.WriteLine(Path.Combine("dir", "subdir", "file.txt"));
+
    Console.WriteLine(Path.Combine("dir", "subdir1", "subdir2", "file.txt"));
+

          
+
    // 配列に格納されたパスの断片
+
    string[] paths = new[] {@"C:\Windows", "Microsoft.NET", "Framework", @"v4.0.30319\clr.dll"};
+

          
+
    Console.WriteLine(Path.Combine(paths));
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Console.WriteLine(Path.Combine("dir", "file.txt"))
+
    Console.WriteLine(Path.Combine("dir", "subdir", "file.txt"))
+
    Console.WriteLine(Path.Combine("dir", "subdir1", "subdir2", "file.txt"))
+

          
+
    ' 配列に格納されたパスの断片
+
    Dim paths() As String = New String() {"C:\Windows", "Microsoft.NET", "Framework", "v4.0.30319\clr.dll"}
+

          
+
    Console.WriteLine(Path.Combine(paths))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
dir\file.txt
+
dir\subdir\file.txt
+
dir\subdir1\subdir2\file.txt
+
C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
+
}}
+

          
+

          
+
*絶対パスの取得・パスの正規化 [#Path.GetFullPath]
+
パスから絶対パスを取得するには&msdn(netfx,member,System.IO.Path.GetFullPath){GetFullPathメソッド};を使います。 このメソッドを呼び出すと``.``や``..``など相対パスを表す文字列が除去された(正規化された)絶対パスが返されます。 相対パスから絶対パスへ変換する際、相対パスは[[カレントディレクトリ>programming/netfx/environment/1_process#ProcessAndAssembly_CurrentDirectory]]を基準としたものとして扱われます。
+

          
+
#tabpage(codelang=cs,container-title=パスの正規化・絶対パスの取得)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // パスの正規化
+
    Console.WriteLine(Path.GetFullPath(@"E:\dir\.\subdir\file.txt"));
+
    Console.WriteLine(Path.GetFullPath(@"E:\dir1\..\dir2\file.txt"));
+

          
+
    // 相対パスから絶対パスへの変換
+
    Console.WriteLine(Path.GetFullPath(@"file.txt"));
+
    Console.WriteLine(Path.GetFullPath(@".\file.txt"));
+
    Console.WriteLine(Path.GetFullPath(@"..\file.txt"));
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' パスの正規化
+
    Console.WriteLine(Path.GetFullPath("E:\dir\.\subdir\file.txt"))
+
    Console.WriteLine(Path.GetFullPath("E:\dir1\..\dir2\file.txt"))
+

          
+
    ' 相対パスから絶対パスへの変換
+
    Console.WriteLine(Path.GetFullPath("file.txt"))
+
    Console.WriteLine(Path.GetFullPath(".\file.txt"))
+
    Console.WriteLine(Path.GetFullPath("..\file.txt"))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(Windows上の.NET Frameworkでの実行結果例){{
+
E:\dir\subdir\file.txt
+
E:\dir2\file.txt
+
c:\Users\smdn\file.txt
+
c:\Users\smdn\file.txt
+
c:\Users\file.txt
+
}}
+

          
+
Linux・Mac環境(Mono)でもディレクトリ区切り文字が``/``になっていればGetFullPathは正しく動作します。
+

          
+
#tabpage(codelang=cs,container-title=パスの正規化・絶対パスの取得)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // パスの正規化
+
    Console.WriteLine(Path.GetFullPath(@"/root/dir/./subdir/file.txt"));
+
    Console.WriteLine(Path.GetFullPath(@"/root/dir1/../dir2/file.txt"));
+

          
+
    // 相対パスから絶対パスへの変換
+
    Console.WriteLine(Path.GetFullPath(@"file.txt"));
+
    Console.WriteLine(Path.GetFullPath(@"./file.txt"));
+
    Console.WriteLine(Path.GetFullPath(@"../file.txt"));
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' パスの正規化
+
    Console.WriteLine(Path.GetFullPath("/root/dir/./subdir/file.txt"))
+
    Console.WriteLine(Path.GetFullPath("/root/dir1/../dir2/file.txt"))
+

          
+
    ' 相対パスから絶対パスへの変換
+
    Console.WriteLine(Path.GetFullPath("file.txt"))
+
    Console.WriteLine(Path.GetFullPath("./file.txt"))
+
    Console.WriteLine(Path.GetFullPath("../file.txt"))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(Linux上のMonoでの実行結果例){{
+
/root/dir/subdir/file.txt
+
/root/dir2/file.txt
+
/home/smdn/file.txt
+
/home/smdn/file.txt
+
/home/file.txt
+
}}
+

          
+

          
+
*相対パスの取得 [#get_relative_path]
+
Pathクラスには絶対パスから相対パスを取得するメソッドは用意されていません。 代わりに&msdn(netfx,type,System.Uri){Uriクラス};を使って相対パスを作成することができます。 以下に紹介する方法では、ファイルパスをURIとして扱い、Uriクラスのメソッドを使って相対パスに変換しています。
+

          
+
#code(cs,Uriクラスを使った相対パスの取得){{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  // basePathを基準としてpathへの相対パスを取得するメソッド
+
  static string GetRelativePath(string basePath, string path)
+
  {
+
    if (basePath == null)
+
      throw new ArgumentNullException("basePath");
+
    if (path == null)
+
      throw new ArgumentNullException("path");
+

          
+
    // 現在Windows上で動作しているかどうか
+
    var isRunningOnWindows = (int)Environment.OSVersion.Platform < 4;
+

          
+
    if (isRunningOnWindows && !Path.IsPathRooted(basePath))
+
      throw new ArgumentException("パスは絶対パスである必要があります", "basePath");
+

          
+
    // URIとして処理する前にパス中の%をURLエンコードする
+
    basePath = basePath.Replace("%", "%25");
+
    path = path.Replace("%", "%25");
+

          
+
    if (!isRunningOnWindows) {
+
      // 非Windows環境ではパスをURIとして解釈させるためにfile://スキームを前置する
+
      basePath = Uri.UriSchemeFile + Uri.SchemeDelimiter + basePath.Replace(":", "%3A");
+
      path     = Uri.UriSchemeFile + Uri.SchemeDelimiter + path.Replace(":", "%3A");
+
    }
+

          
+
    // パスをURIに変換
+
    var uriBase = new Uri(basePath);
+
    var uriTarget = new Uri(path);
+

          
+
    // MakeRelativeUriメソッドで相対パスを取得する
+
    // 同時にURIに変換する際にエスケープされた文字列をアンエスケープする
+
    var relativePath = Uri.UnescapeDataString(uriBase.MakeRelativeUri(uriTarget).ToString());
+

          
+
    // ディレクトリ区切り文字を環境に合わせて置換する
+
    relativePath = relativePath.Replace('/', Path.DirectorySeparatorChar);
+

          
+
    // URLエンコードした%を元に戻す
+
    return relativePath.Replace("%25", "%");
+
  }
+

          
+
  static void Main()
+
  {
+
    if ((int)Environment.OSVersion.Platform < 4)
+
      Console.WriteLine(GetRelativePath(@"E:\dir1\subdir1\subdir2\", @"E:\dir2\ファイル.txt"));
+
    else
+
      Console.WriteLine(GetRelativePath("/dir1/subdir2/subdir2/", "/dir2/ファイル.txt"));
+
  }
+
}
+
}}
+

          
+
#prompt(Windows上の.NET Frameworkでの実行結果){{
+
..\..\..\dir2\ファイル.txt
+
}}
+

          
+
#prompt(Linux上のMonoでの実行結果){{
+
../../../dir2/ファイル.txt
+
}}
+

          
+

          
+
*ルートディレクトリ [#Path.GetPathRoot]
+
&msdn(netfx,member,System.IO.Path.GetPathRoot){GetPathRootメソッド};を使うことでパスからルートディレクトリ部分のみを取得することができます。 例えば、``C:\Windows\Microsoft.NET\Framework``というパスの場合は``C:\``がルートディレクトリ部分となります。 また、パスがルートディレクトリから始まっているかどうかを調べるには&msdn(netfx,member,System.IO.Path.IsPathRooted){IsPathRootedメソッド};を使うことができます。
+

          
+
#tabpage(codelang=cs,container-title=ルートディレクトリの取得)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    Console.WriteLine(Path.GetPathRoot(@"C:\Windows\Microsoft.NET\Framework")); // ドライブ名から始まるパス
+
    Console.WriteLine(Path.GetPathRoot(@"C:")); // ドライブレターのみのパス
+
    Console.WriteLine(Path.GetPathRoot(@"dir\file.txt")); // 相対パス
+

          
+
    Console.WriteLine(Path.IsPathRooted(@"C:\Windows\Microsoft.NET\Framework"));
+
    Console.WriteLine(Path.IsPathRooted(@"C:"));
+
    Console.WriteLine(Path.IsPathRooted(@"dir\file.txt"));
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Console.WriteLine(Path.GetPathRoot("C:\Windows\Microsoft.NET\Framework")) ' ドライブ名から始まるパス
+
    Console.WriteLine(Path.GetPathRoot("C:")) ' ドライブレターのみのパス
+
    Console.WriteLine(Path.GetPathRoot("dir\file.txt")) ' 相対パス
+

          
+
    Console.WriteLine(Path.IsPathRooted("C:\Windows\Microsoft.NET\Framework"))
+
    Console.WriteLine(Path.IsPathRooted("C:"))
+
    Console.WriteLine(Path.IsPathRooted("dir\file.txt"))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+

          
+
#prompt(Windows上の.NET Frameworkでの実行結果){{
+
C:\
+
C:
+

          
+
True
+
True
+
False
+
}}
+

          
+
Linux・Mac環境(Mono)では、常にパス先頭の``/``がルートディレクトリとして扱われます。
+

          
+
#code(cs){{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    Console.WriteLine(Path.GetPathRoot("/root/dir/"));
+
    Console.WriteLine(Path.GetPathRoot("/"));
+
    Console.WriteLine(Path.GetPathRoot("dir/file.txt"));
+
    Console.WriteLine(Path.GetPathRoot(@"C:\Windows\Microsoft.NET\Framework")); // Windows形式のパス
+

          
+
    Console.WriteLine(Path.IsPathRooted("/root/dir/"));
+
    Console.WriteLine(Path.IsPathRooted("/"));
+
    Console.WriteLine(Path.IsPathRooted("dir/file.txt"));
+
    Console.WriteLine(Path.IsPathRooted(@"C:\Windows\Microsoft.NET\Framework"));
+
  }
+
}
+
}}
+

          
+
#prompt(Linux上のMonoでの実行結果){{
+
/
+
/
+

          
+

          
+
True
+
True
+
False
+
False
+
}}
+

          
+

          
+

          
+
*パスやファイル名に使用できない文字
+
一部の記号はパスやファイル名に使うことができません。 ファイル名に使用できない文字は&msdn(netfx,member,System.IO.Path.GetInvalidFileNameChars){GetInvalidFileNameCharsメソッド};、パスに使用できない文字は&msdn(netfx,member,System.IO.Path.GetInvalidPathChars){GetInvalidPathCharsメソッド};によって取得できます。 これらのメソッドはユーザーによって入力されたファイル名やパスに使用できない文字が含まれているか検証したり別の文字に置き換えたりする場合に使用することができます。 なお、これらの文字はプラットフォームによって異なります。 詳しくは[[programming/netfx/environment/0_platform#SystemAndPlatform_DirectorySeparatorChar]]で解説しています。
+

          
+
使用不可能な文字を含まないファイル名を生成する必要がある場合は&msdn(netfx,member,System.IO.Path.GetRandomFileName){GetRandomFileNameメソッド};を使うことができます。 このメソッドはランダムな文字列からなるファイル名を生成して返します。 このメソッドで作成されるのはファイル名(文字列)だけで、ファイル自体は作成されません。
+

          
+
#tabpage(codelang=cs,container-title=ランダムなファイル名の生成)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // ランダムなファイル名を10個生成する
+
    for (int i = 0; i < 10; i++) {
+
      Console.WriteLine(Path.GetRandomFileName());
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' ランダムなファイル名を10個生成する
+
    For i As Integer = 0 To 9
+
      Console.WriteLine(Path.GetRandomFileName())
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果例){{
+
hoksydgk.ic2
+
njge1wrb.o33
+
nqnvcxwr.cui
+
l5kjak0c.eix
+
khuaxu11.onp
+
1ukhqw0f.opm
+
jifclgdc.m1o
+
ge1qi1ah.udi
+
2aczb3ka.0if
+
l5cvnbej.mtk
+
}}
+

          
+
一時ファイルの作成が必要な場合は&msdn(netfx,member,System.IO.Path.GetTempFileName){GetTempFileNameメソッド};を使うこともできます。 このメソッドはGetRandomFileNameメソッドとは異なり実際にファイルを作成した上でそのファイル名を返します。
+

          
+

          
+

          
+
#navi(..)
+