トップC# > ファイルの操作

ファイルの操作

ファイル/ディレクトリの存在をチェックする

ファイルの存在は パス名を引数としてFile.Exitsメソッドを使う。 ファイルが存在すれば true、存在しなければ false が返される。

同様にディレクトリがあるか調べるには、System.IO.Directory.Existsメソッドを使う。

  System.IO.File.Exists(path)
 ディレクトリを作成するには、DirectoryクラスのCreateDirectoryメソッドを使用する。
  System.IO.Directory.CreateDirectory(path);

ファイルの一括読み込み・書き込み

File.ReadAllTextメソッドでテキストファイル全体を読み込むことができる。

File.WriteAllTextメソッドでテキストをファイルに一括して書き込むことができる。

IEnumerable<string> File.ReadLines(string path) メソッドでテキストファイルの全行を一括して 読み込むことができる。

// シフトJISのファイルの読み込み・書き込み
string sjis_html = File.ReadAllText(@"c:\shift_jis.html", System.Text.Encoding.GetEncoding("Shift_JIS"));
File.WriteAllText(@"c:\shift_jis.html", sjis_html, System.Text.Encoding.GetEncoding("Shift_JIS"));

// UTF-8のファイルの読み込み・書き込み
string utf8_html = File.ReadAllText("utf8.html", System.Text.Encoding.GetEncoding("utf-8"));
File.WriteAllText(@"c:\utf8.html", utf8_html, System.Text.Encoding.GetEncoding("utf-8"));

バイナリファイルに対しては File.ReadAllBytesメソッドおよびFile.WriteAllBytesを使う。

// バイナリ・ファイルの読み込み
 byte[] img = File.ReadAllBytes("sea1.png");

// バイナリ・ファイルの書き込み
 File.WriteAllBytes("sea2.png", img);

File.ReadAllTextメソッドおよび File.ReadAllBytesメソッドで指定されたファイルが存在しないときはエラーとなる (FileNotFoundExceptionがスローされる)。

テキストファイルの行単位の読み込み・書き込み

テキストファイルの行単位の読み込みはStreamReaderクラスのReadLine()メソッドを使う。 プログラム例を下に示す。

  using (StreamReader reader = new StreamReader(filepath)) {
    while (reader.Peek() >= 0) {
      string line = reader.ReadLine();
      Console.WriteLine(line);
    }
  }

IEnumerable<string> File.ReadLines(string path) メソッドを使った場合は次のようになる。

  IEnumerable<string> lines = File.ReadLines(filepath);
  foreach (string line in lines) {
    Console.WriteLine(line);
  }

行単位の書き込みは StreamWriterクラスの WriteLineメソッドを使用する。 コンソール出力 System.Console.WriteLineメソッドと同様である。

下に、StreamWriterの使用例を示す。あるプログラムから、関係する部分を抜き出したものである。

  int X = (int)Math.Floor(point.X);
  int Y = (int)Math.Floor(point.Y);
  StreamWriter writer = new StreamWriter(DIR+X+"/"+Y+".csv", true, sjisEnc);
  writer.WriteLine(strRecord);
  writer.Close();

sjisEncは予め次のように設定されている。 StreamWriterコンストラクタの第2引数の true は追記モードを表す。 第1引数で指定されたファイルが存在しなければ新しくファイルが生成され、文字列strRecordが 末尾に改行コードを付加して書き込まれる。指定ファイルが存在した場合には、 その後ろに今回のデータが書き込まれる。

第2引数を false とした場合には、以前の内容は無視され、ここで新たに書き込んだ文字列データのみとなる。

  Encoding sjisEnc = Encoding.GetEncoding("Shift_JIS");

なお、ディレクトリ自体が存在しない場合には、自動的にはディレクトリまで作成されるわけではない。 従って、ディレクトリが存在しない可能性がある場合には、まず、ディレクトリが存在するかどうかチェックして、 存在しない場合には、ディレクトリを生成する必要がある。 ここで取り上げたプログラムでは、次のようにしている。

  int X = (int)Math.Floor(point.X);
  int Y = (int)Math.Floor(point.Y);
  if (!Directory.Exists(DIR + X)) {
    Directory.CreateDirectory(DIR + X);
  }
  StreamWriter writer = new StreamWriter(DIR+X+"/"+Y+".csv", true, sjisEnc);
  writer.WriteLine(strRecord);
  writer.Close();

ファイルのパスからディレクトリを抽出する

例えばファイルのパス ../_db/life/master.csv からディレクトリ ../_db/life を得るには Path.GetDirectoryName("../_db/life/master.csv") とすればよい。

ファイルのタイムスタンプを更新する

  using System.IO;

  const string path = @"c:\timestamp.txt";
  File.SetCreationTime(path, DateTime.Now);   // 作成日時を現在のローカル時刻で更新する
  File.SetLastWriteTime(path, DateTime.Now);  // 更新日時を現在のローカル時刻で更新する
  File.SetLastAccessTime(path, DateTime.Now); // アクセス日時を現在のローカル時刻で更新する

ファイルのタイムスタンプを取得する

  using System.IO;

  const string path = @"c:\timestamp.txt";
  DateTime dtCreate = File.GetCreationTime(path);   // 作成日時を取得する
  DateTime dtUpdate = File.GetLastWriteTime(path);  // 更新日時を取得する
  DateTime dtAccess = File.GetLastAccessTime(path); // アクセス日時を取得する

特定の時刻ではなく、複数の種類の時刻やファイルサイズなどいくつかの情報を得る場合には FileInfoクラス(CreationTime, LastWriteTime, Lengthプロパティなど)を使う方が効率がよい。

ファイルサイズを取得する

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

  System.IO.FileInfo fi = new System.IO.FileInfo("c:/tmp.txt");
  long filesize = fi.Length;

ファイルを削除する

ファイルを削除するにはFileクラスのDeleteメソッドを使う。パス名にワイルドカードを含めることはできない。

  System.IO.File.Delete("c:/tmp.txt");

ファイル名を変更する、ファイルを移動する

ファイル名の変更やファイルの移動にはFileクラスのMoveメソッドを使う。

  System.IO.File.Move("c:/oldname.txt", "c:/newname.txt");

引数には カレント・ディレクトリのファイルや、ファイルの相対パス、ファイルの絶対パスを指定することができる。

移動先のディレクトリやドライブが異なっていてもよい。

ファイルをコピーする

ファイルをコピーするにはFileクラスのCopyメソッドを使う。

  System.IO.File.Copy("c:/src.txt", "c:/dst.txt");

コピー先のファイルが既に存在していた場合には例外(エラー)が発生する。 存在した場合、上書きしたいときは、第3引数を True とする。

  System.IO.File.Copy("c:/src.txt", "c:/dst.txt", True);

バイナリ・ファイルの内容を比較する

C#ではバイナリ・ファイルの内容を比較するのは極めて簡単である。 ReadAllBytesメソッドでファイルをバイト配列として読み込み、 SequenceEqualメソッドで比較すればよい。

  // using System.Linq;

  byte[] byte1 = File.ReadAllBytes(file1);
  byte[] byte2 = File.ReadAllBytes(file2);
  bool fMatch = byte1.SequenceEqual(byte2);

指定されたディレクトリ下の全てのファイルのパス名一覧を得る

次のようにして、dir下の全て(サブディレクトリ下を含む)のファイルのパス名配列を得ることができる。

  string[] files = Directory.GetFiles(dir, "*", SearchOption.AllDirectories);

次のようにすれば、拡張子が html だけのものを得ることができる。

  string[] files = Directory.GetFiles(dir, "*.html", SearchOption.AllDirectories);