【実践】C#ファイル/フォルダ操作術。すぐに使えるサンプルコード付き

当ページのリンクには広告が含まれています。

C#でファイルやフォルダ操作を行う代表的なクラスとして、System.IO.File、System.IO.Directory、System.IO.Pathがあります。

今回は、これらクラスの役割について図で整理したうえで、やりたいこと別にメソッドの使い方を、サンプルコードを付けて解説していきます。

また最後の章では、これらを使った実用サンプルも掲載しています。実用サンプルは自由にコピペ可能ですので、ご自身の用途に合わせて修正の上、ご活用ください。

C#によるファイルの読み書きの詳細については、「【C#】ファイルの読み書き基礎と実践。コピペで使える実用サンプル満載!」で紹介していますので、こちらも併せてご覧下さい。

目次

ファイル/フォルダ操作クラスの全体像

.NET でファイルやフォルダを扱うクラスは3種類用意されていますが、それぞれ次の役割を持っています。

クラス名役割
System.IO.Fileファイルの作成、コピー、削除、移動などの基本的な操作を行うためのクラスです。ファイルの読み書きも行えます。
System.IO.Directoryディレクトリ(フォルダ)の作成、削除、移動などの操作を行うためのクラスです。
System.IO.Pathファイルパスやディレクトリパスの操作を行うためのクラスです。パスの結合や解析、拡張子の取得などが可能です。

用途別クラス・メソッド紹介

今回紹介する3つのクラスは、全て System.IO 名前空間に含まれていますので、ここからは記述を省略しています。

ファイルやフォルダの存在確認

存在確認は Fileクラス、Directoryクラス、Pathクラスそれぞれに用意されていますが、下表の通り判定結果が異なります。

機能クラス・メソッド説明
ファイルの存在確認bool File.Exists(string path)path がファイルならtrue、
それ以外ならfalseを返します。
フォルダの存在確認bool Directory.Exists(string path)path がフォルダならtrue、
それ以外ならfalseを返します。
ファイル又はフォルダの存在確認bool Path.Exists(string path)path がファイル又はフォルダならtrue
それ以外ならfalseを返します。

フォルダやファイルの新規作成

Fileクラスを使うと文字列や配列の中身を簡単にファイルに出力することが出来ます。
また、フォルダについても作成したいフォルダのパスを指定するだけす。

パスは "D:\AAA\BBB\CCC\DDD" の様に階層を含めて指定することが可能で、この場合は最後のDDDに到達する過程のフォルダも自動的に作成されます。

機能クラス・メソッド説明
ファイルの作成void File.WriteAllText(
string path,
string contents,
Encoding encoding
)
contents で指定した文字列をファイルに保存します。
文字コードは encoding で指定しますが、省略すると UTF-8として保存されます。
void File.WriteAllLines(
string path,
IEnumerable<string> lines,
Encoding encoding
)
linesで指定した文字列配列(string[] 又は List<string>)をファイルに保存します。
文字コードは encoding で指定しますが、省略すると UTF-8として保存されます。
フォルダの作成DirectoryInfo Directory.CreateDirectory(
string path
)
指定されたパスにフォルダを作成します。
パスに階層を指定すると、その階層までフォルダが作成されます。
既に存在すれば何もしません。
フォルダの有無に関わらず、DirectoryInfoを返します。

フォルダ又はファイルのリネーム

Renameなど名前を変更するメソッドが無いので、ファイル/フォルダを移動するためのMoveメソッドを代用して名前変更します。

既にファイルやフォルダが存在する場合は次の例外が発生します。
  Cannot create 'o:\test' because a file or directory with the same name already exists.'

機能クラス・メソッド説明
ファイルの名前変更void File.Move(
string sourceName,
string destName
)
ファイル名 sourceName を destName に変更します。
フォルダの名前変更void Directory.Move(
string ourceName,
string destName
)
フォルダ名 sourceName を destName に変更します。

ファイル又はフォルダのコピー

ファイルはコピーできますが、フォルダを丸ごとコピーするメソッドは用意されていません。フォルダ階層丸ごとのサンプルコードを掲載しましたので、併せてご活用ください。

機能クラス・メソッド説明
ファイルの名前変更void File.Copy(
string sourcePath,
string destPath,
bool overWrite
)
sourcePath で指定したファイルを destPathで指定した場所にコピーします。
overWrite は省略可能で、初期値は false になっています。既に存在した時は上書きしたい場合は true を指定します。
フォルダの名前変更該当なしフォルダ階層ごとコピーできるメソッドが存在しないので、後述する自作メソッドを使う必要があります。

マイクロソフトの公式サイトにサンプルが掲載されていますが、コピー元フォルダにアクセス権が無いフォルダが含まれると例外が発生して処理が止まるため、例外処理を実装したサンプルを紹介しておきます。

ファイル又はフォルダの削除(ゴミ箱に残す方法を含む)

ファイル、フォルダともに削除メソッドが用意されており、フォルダの削除は配下の階層ごと削除が可能です。尚、メソッドを使った削除は込み箱に残らないのでご注意ください。

もしゴミ箱に残したい場合は、後述する VisualBasic.FiieIO名前空間のDeleteメソッドを使う必要があります。

機能クラス・メソッド説明
ファイルの削除void File.Delete(
string path
)
指定されたファイルを削除します。
フォルダの削除void Directory.Delete(
string path,
bool recursive
)
指定されたフォルダを削除します。
第2引数の recursive を省略すると、空のフォルダしか削除できません(省略時は false が指定される)。
フォルダの中身を階層ごと削除する場合は true を指定します。

削除した内容をゴミ箱に残すには、Microsoft.VisualBasic.FileIO名前空間にある DeleteFIle、DeleteDirectory メソッドを使います。

ファイル又はフォルダの移動

名前変更で紹介したMoveメソッドを使ってファイルやフォルダを移動します。

ただし、Windowsでは同じドライブ内での移動しかサポートされていません。仮に CドライブからDドライブに移動するような場合、以下の例外が発生します。
 System.IO.IOException: 'Source and destination path must have identical roots. Move will not work across volumes.'

異なるドライブ間での移動はCopyとDeleteを組み合わせて実現します(詳細は後述)。

機能クラス・メソッド説明
ファイルの移動void File.Move(
string sourcePath,
string destPath
)
ファイルを sourceName から destName に移動します。
フォルダの移動void Directory.Move(
string sourcePath,
string destPath
)
フォルダを sourceName から destName にフォルダ階層ごと移動します。

異なったドライブに移動したい場合は、Copy メソッドと Delete メソッドを組み合わせて実現します。Copyメソッドは戻り値が無いので、成功したか否かが判定できません。

そこで、例外処理の try~catch で囲み、その中にCopy と Delete を続けて実行することで、コピーが成功した時のみ元のファイルが削除されるようにしています。

フォルダについては階層ごとのコピーが出来ないので、前述「ファイル又はフォルダのコピー」で紹介した自作メソッドを try~catchの中で呼ぶことで実現します。

この方法では、フォルダコピーが完了しないと元のフォルダは削除されません。
これはある意味安全ではありますが、Windows標準のエクスプローラーでフォルダを移動する時の様に、途中で失敗してもそれまでに移動したものが元から消したい場合もあるでしょう。

その場合は、File.Copy(file, destFile, true) の部分を try~catch で囲み、そのかに File.Delete も一緒に入れておくことで対応が可能です。

ファイルまたはフォルダ一覧の取得(参照権限が無いフォルダを含む)

機能クラス・メソッド説明
ファイルの移動string[] Directory.GetFiless(
string path,
string serchPattern,
SearchOption searchOption
)
指定した場所にあるファイルの一覧を取得します。
serchPattern、searchOption 共に省略可能です。
searchPattern にワイルドカードを指定することで、パターンに一致するフォルダのみ取得可能です。
searchOption に AllDirectories を指定するとフォルダ階層下を含む全てのファイルが取得可能です。
フォルダの移動string[] Directory.GetDirectories(
string path,
string serchPattern,
SearchOption searchOption
)
指定した場所にあるフォルダの一覧を取得します。
serchPattern、searchOption 共に省略可能です。
searchPattern にワイルドカードを指定することで、パターンに一致するフォルダのみ取得可能です。
searchOption に AllDirectories を指定するとフォルダ階層下を含む全てのフォルダが取得可能です。

D:\Images\00388-846986118.png
D:\Images\00389-846986119.png
D:\Images\00390-846986120.png
D:\Images\00395-2819340012.png
D:\Images\Backup\00396.png
D:\Images\Backup\風景.png
D:\Images\Resize\Small\IMG01250.png
D:\Images\Resize\Small\IMG01255.png

D:\backup\images
D:\backup\images2
D:\backup\images3
D:\backup\images\ImageResize
D:\backup\images\ImgList

指定したパスの全階層からファイルを取得する場合、その中にアクセス権限が無いフォルダが存在すると、次の例外が発生します。例えばCドライブやDドライブのルートを指定すると、ほぼ確実に次の例外が発生します。

System.UnauthorizedAccessException: 'Access to the path 'P:\System Volume Information' is denied.'

これを回避するためには、フォルダ1つ1つに対してアクセスしつつ、例外が発生した時は無視するような処理が必要です。

下記は、検索対象に権限が無いフォルダが含まれていた場合、それを無視してファイル一覧を取得するサンプルコードです。IEnumerable<string>型の戻り値なので、 foreachループで1つづつ受け取るか、.ToArray() でまとめて受け取るかしてください。

ファイルパスの操作(フォルダ名やファイル名の分割、結合)

機能クラス・メソッド説明
フォルダ名の分離string Path.GetDirectoryName(
string path
)
指定されたパス文字列のフォルダ名部分を取得します。ファイル名と拡張子は含まれません。
ファイル名の分離string Path.GetFileName(
string path
)
指定されたパス文字列のファイル名と拡張子を取得します。フォルダ部分は含まれません。
ファイル名の取得string Path.GetFileNameWithoutExtension(
string path
)
指定されたパス文字列の拡張子を除いたファイル名を取得します。ディレクトリ部分は含まれません。
拡張子の取得string Path.GetExtension(
string path
)
指定されたパス文字列の拡張子部分を取得します。先頭にピリオド '.' が付加されます。
例 :".jpg"
パスのルートの取得string Path.GetPathRoot(
string path
)
指定されたパス文字列のルートディレクトリ(ドライブ名)を取得します。
例:"d:\"
フォルダ名の結合string Path.Combine(
string path1,string path2,・・・
)
複数の文字列からパスを構築します。各部分が自動的に適切に連結され、重複するディレクトリ区切り記号は除去されます。

ファイル、フォルダ操作の実用事例

ワイルドカードに一致するファイルを対象にフォルダを丸ごとコピー

CopyFilesWithFilterメソッドは、sourceFolderで指定されたフォルダ階層を丸ごとdestinationFolderで指定されたフォルダ配下にコピーする関数です。

CopyFilesWithFilter(sourceFolder, destinationFolder ,wildcardPattern,filterFunc=null)

特徴としては、第3引数にワイルドカードが指定でき、かつ コールバック関数を用いて filterFunc フィルター条件が指定できる点です。

次のソースコードはコールバック関数のサンプルです。コピー対象となるファイルの最終更新日時が、直近5日以降になら true、以前なら falseを返します。これをCopyFilesWithFilterの第4引数に指定することで、指定日時より以降に作成されたファイルのみコピーすることができます。

2つのフォルダを比較して、それぞれの差分を抽出する

FolderDiff メソッドは、sourceFolderで指定されたフォルダと、targetFolderで指定フォルダに対して、階層下にある全てのファイルを比較し、それぞれの差分をタプルで返します。

var result = FolderDiff(sourceFolder, targetFolder,wildcardPattern)

戻り値は、元のフォルダにのみ存在するファイル(uniqueSourceFiles)のリストと、比較先のフォルダにのみ存在するファイル(uniqueTargetFiles)のリストです。

FolderDiffメソッドの使い方は次の通りです。このサンプルコードでは、Dドライブ直下のimages フォルダと Eドライブ直下にある backup フォルダの差分を抽出しています。

まとめ

今回は、C#でファイルやフォルダ操作を行う代表的な3つのクラス、System.IO.File、System.IO.Directory、System.IO.Path について、やりたい事にメソッドを整理して紹介しました。

フォルダ階層丸ごとのコピーや移動については .NET 標準のメソッドが用意されていないため、本記事ではコピペで利用可能な関数のサンプルとして具体的なソースコードを紹介しました。

また、フォルダ階層化を含むファイル一覧の取得についても、アクセス権限が無いフォルダが含まれていても無視する(例外を発生させない)サンプルコードを紹介しました。

System.IO.File、System.IO.Directory、System.IO.Path に実装されているメソッドは、今回紹介したもの以外にも数多く存在し、また 紹介していないクラスも多々ありますが、今回紹介したメソッドさえ理解していれば、よほど特殊なことをしない限り困ることは無いかと思います。

今回の記事が皆さんのお役に立てば幸いです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次