ファイル操作

ここではファイルを操作する方法を説明します。
フォルダの操作はフォルダ操作を参照してください。

ファイルの操作にはFileクラスを使用します。
Fileクラスは「System.IO」名前空間に存在するので、コード先頭のusingディレクティブに以下を追加してください。


using System;

//↓なければこれを追加
using System.IO;

ファイルというのは他のプログラムからも使用されることがあるので、ファイル操作は比較的エラーの起きやすい処理です。
何らかの理由でファイル操作に失敗した場合はエラー(例外)が発生します。

以下のサンプルコードはエラー処理は省いています。
エラーに適切に対処するには例外を参照してください。

ファイルの存在確認

指定のパスにファイルが存在するかをチェックするにはFile.Existsメソッドを使用します。


string path = "test.txt";

if (File.Exists(path))
    Console.WriteLine("{0}は存在する", path);
else
    Console.WriteLine("{0}は存在しない", path);

//FileクラスはSystem.IO内にある
//System.IO.File

File.Existsメソッドは引数に指定したパスが存在する場合は真を、存在しなければ偽を返します。
パスは相対パスまたは絶対パスで指定します。

フォルダの存在確認はできない

File.Existsメソッドはあくまでもファイルの存在確認をするメソッドで、フォルダの存在確認はできません。
フォルダの存在確認をするにはフォルダ操作フォルダの存在確認を参照してください。

ファイルのコピー

既存のファイルをコピーするにはFile.Copyメソッドを使用します。


string pathSource = "test.txt";
string pathDest = "test_copy.txt";

if (!File.Exists(pathSource))
{
    Console.WriteLine("{0}が見つかりません。", pathSource);
    Console.ReadLine();
    return;
}
if (File.Exists(pathDest))
{
    Console.WriteLine("{0}はすでに存在します。", pathDest);
    Console.ReadLine();
    return;
}

//"test.txt"を"test_copy.txt"としてコピー
File.Copy(pathSource, pathDest);

Console.WriteLine("{0}を{1}としてコピーしました。", pathSource, pathDest);
Console.ReadLine();

File.Copyメソッドはコピー元が存在しない場合はエラー(例外)が発生します。
また、コピー先にすでに同名のファイルが存在する場合もエラー(例外)となります。

File.Copyメソッドの第三引数にtrueを指定すると、ファイルが存在する場合は上書きします。
(存在しない場合の動作は同じ)


string pathSource = "test.txt";
string pathDest = "test_copy.txt";

//"test.txt"を"test_copy.txt"としてコピー
//コピー先にファイルが存在する場合は上書き
File.Copy(pathSource, pathDest, true);

Console.WriteLine("{0}を{1}としてコピーしました。", pathSource, pathDest);
Console.ReadLine();

ファイルの作成やコピー、削除などのメソッドを使用する場合、目的のファイルの存在の有無によってエラー(例外)が発生することがあります。
これを回避するには、普通は処理の直前でFile.Existsメソッドでファイルの存在の確認して処理を分けるだけで十分です。

しかしファイルというのは別のプログラムからもアクセスが可能なため、File.Existsメソッドの実行後と実際のファイル操作とのわずかな間に目的のファイルの状態が変更される可能性もゼロではありません。
そのため、極力エラーを起こさないようにするにはやはり例外処理が必要になります。

ファイルの移動(名前の変更)

ファイルを移動するにはFile.Moveメソッドを使用します。


string pathSource = "test.txt";
string pathDest = "test_move.txt";

if (!File.Exists(pathSource))
{
    Console.WriteLine("{0}が見つかりません。", pathSource);
    Console.ReadLine();
    return;
}

//"test.txt"を"test_move.txt"に移動
//リネームと同義
File.Move(pathSource, pathDest);

Console.WriteLine("{0}を{1}に移動しました。", pathSource, pathDest);
Console.ReadLine();

ファイルの移動というのはファイル名を変更するのと同じ処理をすることになります。
サンプルコードでは移動元と移動先が同じフォルダ内なのでリネーム処理になりますが、別のフォルダを指定すれば移動処理になります。

File.MoveメソッドはFile.Copyメソッドのように移動先のファイルが存在する場合に上書きして移動することはできません。
(例外が発生します)
上書きしたい場合は後述するFile.Deleteメソッドであらかじめファイルを削除してから移動します。

ファイルの削除

ファイルを削除するにはFile.Deleteメソッドを使用します。


string pathSource = "test.txt";

if (!File.Exists(pathSource))
{
    Console.WriteLine("{0}が見つかりません。", pathSource);
    Console.ReadLine();
    return;
}

//"test.txt"を削除
File.Delete(pathSource);

Console.WriteLine("{0}を削除しました。", pathSource);
Console.ReadLine();

File.Deleteメソッドは指定のファイルが存在しなくてもエラーにはなりません。
そのためFile.Existsメソッドは使用しなくても問題ありませんが、処理結果の表示を振り分けたいのでサンプルコードでは使用しています。

指定のファイルが読み取り専用の場合はエラー(例外)が発生します。

ファイルの属性

ファイルには「読み取り専用」や「隠しファイル」などの属性が存在します。
これを取得、設定するにはFileAttributes列挙型を使用します。
(System.IO.FileAttributes)

まず以下にFileAttributes列挙型の値を示します。
(Microsoft Docsより抜粋)

名前説明
Archive32ファイルは、バックアップまたは削除の候補です。
Compressed2048ファイルは圧縮ファイルです。
Device64将来使用するために予約されています。
Directory16ファイルはディレクトリです。
Encrypted16384ファイルまたはディレクトリは暗号化されています。 ファイルの場合は、ファイルのすべてのデータが暗号化されています。 ディレクトリの場合は、新規作成されるファイルおよびディレクトリが既定で暗号化されます。
Hidden2ファイルは隠しファイルです。したがって通常のディレクトリ リストには表示されません。
IntegrityStream32768ファイルまたはディレクトリには、データ整合性のサポートが含まれます。 この値がファイルに適用されると、ファイルのすべてのデータ ストリームは整合性サポートを持ちます。 この値がディレクトリに適用されると、そのディレクトリ内のすべての新しいファイルとサブディレクトリは、既定で一貫性サポートを含みます。
Normal128ファイルは、特別な属性を持たない標準ファイルです。 この属性は、単独で使用された場合のみ有効です。
NoScrubData131072ファイルまたはディレクトリは、データ整合性のスキャン対象から除外されます。 この値がディレクトリに適用されると、そのディレクトリ内のすべての新しいファイルとサブディレクトリが既定でデータ一貫性から除外されます。
NotContentIndexed8192ファイルは、オペレーティング システムによるコンテンツ インデックス サービスでインデックスされません。
Offline4096ファイルはオフラインです。 オフラインのファイルのデータは、即時には使用できません。
ReadOnly1ファイルは読み取り専用です。
ReparsePoint1024ファイルには、ファイルまたはディレクトリに関連付けられたユーザー定義のデータ ブロックである、リパース ポイントが含まれています。
SparseFile512ファイルはスパース ファイルです。 スパース ファイルは、通常、データの大部分が 0 である大きなファイルです。
System4ファイルはシステム ファイルです。 つまり、このファイルはオペレーティング システムの一部であるか、オペレーティング システムによって排他的に使用されます。
Temporary256一時ファイルです。 一時ファイルには、アプリケーションを実行中は必要で、アプリケーションを終了すると不要になるデータが含まれています。 ファイル システムは、データを大容量ストレージにフラッシュするのではなく、すべてのデータをメモリに保持するよう試みて、すばやくアクセスできるようにします。 一時ファイルが不要になったら、アプリケーションが直ちに削除する必要があります。

ファイルの属性というのは複数同時に設定されることがあります。
FileAttributes列挙型の値は1から順に値を倍にした数値が設定されています。
これはビット演算を使用して値を取得、設定するときに使用される方法です。
(ビット演算に関して詳しくは上記ページを参照してください)
実際の数値は特に気にする必要はありません。

ファイルの属性を取得

ファイルの属性を取得するにはFile.GetAttributesメソッドを使用します。


//以下のファイルは存在するものとする
string path = "test.txt";

//「C:\test.txt」の属性を取得
FileAttributes attrFile = File.GetAttributes(path);

//attrFileに「ReadOnly」属性が設定されているかを取得
FileAttributes attr = attrFile & FileAttributes.ReadOnly;

//ReadOnly属性が取得できているか
if (attr == FileAttributes.ReadOnly)
{
    Console.WriteLine("{0}は読み取り専用です。", path);
}
else
{
    Console.WriteLine("{0}は読み取り専用ではありません。", path);
}

//短縮形
if ((attrFile & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
{
}

File.GetAttributesメソッドの戻り値は指定のファイルに設定されているすべての属性です。
そこから特定の属性を取り出すには「&」記号を使用します。
(これがビット演算)
attrFileにReadOnly属性が含まれていればReadOnlyが返され、含まれていなければ「0」が返されます。

ファイルの属性を設定

ファイルの属性を設定するにはFile.SetAttributesメソッドを使用します。


//以下のファイルは存在するものとする
string path = "test.txt";

//「C:\test.txt」の属性を取得
FileAttributes attrFile = File.GetAttributes(path);

//「ReadOnly」属性を追加
attrFile = attrFile | FileAttributes.ReadOnly;

//新しい属性を設定
File.SetAttributes(path, attrFile);

File.SetAttributesメソッド自体の使い方は難しいものではありません。
第一引数にファイルのパスを、第二引数に新しい属性を指定するだけです。

問題はビット演算の方法でしょう。
以下に「追加」「削除」「反転」の例を示します。
詳しくはビットフィールドの項を参照してください。


string path = "test.txt";            
FileAttributes attr = File.GetAttributes(path);

//「ReadOnly」属性を追加
attr = attr | FileAttributes.ReadOnly;

//「ReadOnly」属性を削除
attr = attr & ~FileAttributes.ReadOnly;

//「ReadOnly」属性を反転
//(あれば削除、なければ追加)
attr = attr ^ FileAttributes.ReadOnly;

ファイルサイズの取得

ファイルサイズを取得するにはFileInfoクラスのLengthプロパティを使用します。


string path = "test.txt";

//FileInfoインスタンスを作成
FileInfo fileInfo = new FileInfo(path);

//ファイルサイズを取得
long filesize = fileInfo.Length;

Console.WriteLine(filesize);

Console.ReadLine();

FileInfoクラスはファイルに関する情報を扱うクラスです。
(System.IO.FileInfo)
FileInfoクラスを使用するにはnewキーワードを使用してクラスのインスタンスを作成する必要があります。
(このあたりのことはクラスの解説で改めて説明します)

FileInfoインスタンスのLengthプロパティには指定のファイルのファイルサイズが格納されています。
LengthプロパティはLong型です。