FileStreamクラスはファイルに対して読み書きを行うためのStreamです。 Streamクラスから派生したクラスであるため、ほとんどの機能と操作方法はStreamクラスと同じであることから、その部分については省略します。 ここではFileStreamクラスに特有な箇所についてのみ解説します。

FileStreamを使った読み込み・書き込み等の操作についてはStreamクラスStreamReaderクラス・StreamWriterクラスBinaryReaderクラス・BinaryWriterクラスを参照してください。 また、FileStreamを使わずFileクラスのメソッドでファイルを読み書きする方法についてはファイル入出力を参照してください。

§1 インスタンスの作成とオプション

FileStreamのインスタンスを作成する際、コンストラクタにはファイル名以外にもいくつかオプションを指定することができます。 例えば、読み込み専用で開くか読み書きの両方ができるように開くか、既存のファイルを開くか新しくファイルを作成して開くか、同一ファイルに対する排他的アクセス・共有を許可するかどうか、などのオプションを細かく設定することが出来ます。 指定できるオプションには以下のようなものがあります。

§1.1 FileMode

FileMode列挙体は、ファイルをどのようなモードで開くかを指定するためのものです。 FileMode列挙体の値の意味は、開こうとするファイルが既に存在してるかどうかで動作が変わります。 値の意味と動作を表にまとめると次のようになります。

FileModeの値と動作
FileModeの値と意味 ファイルが存在する場合の動作 ファイルが存在しない場合の動作 操作に対する制限
FileMode.Open
(必ず存在するファイルを開く)
既存のファイルを開く FileNotFoundExceptionがスローされる -
FileMode.OpenOrCreate
(存在するファイルを開くか、新しく作成して開く)
既存のファイルを開く 新しくファイルを作成して開く -
FileMode.CreateNew
(必ず新しくファイルを作成して開く)
IOExceptionがスローされる 新しくファイルを作成して開く -
FileMode.Create
(新しくファイルを作成して開く)
既存のファイルを開き、既存の内容を破棄する 新しくファイルを作成して開く -
FileMode.Truncate
(ファイルを切り詰めて開く)
既存のファイルを開き、既存の内容を破棄する 新しくファイルを作成して開く 読み込み操作は出来ない
FileMode.Append
(追記のみを行う目的でファイルを開く)
既存のファイルを開き、末尾にシークする 新しくファイルを作成して開く 末尾より前へのシークは出来ない
FileAccessはWriteでなければならない

§1.2 FileAccess

FileAccess列挙体は、開いたFileStreamに対して許可する読み書きアクセスを指定するためのものです。

FileAccessの値と動作
FileAccessの値 意味と動作
FileAccess.ReadWrite 読み込み・書き込みの両方を許可する
CanRead・CanWriteともにtrueとなる
(FileAccessを指定しなかった場合のデフォルト)
FileAccess.Read 読み込みのみを許可する
CanWriteはfalseとなる
Writeメソッドを呼び出した場合は例外NotSupportedExceptionがスローされる
FileAccess.Write 書き込みのみを許可する
CanReadはfalseとなる
Readメソッドを呼び出した場合は例外NotSupportedExceptionがスローされる

FileAccessの指定は、ファイル属性における読み取り専用とは異なります。 例えばファイル属性に読み取り専用が設定されているファイルの場合、FileAccess.ReadWriteまたはFileAccess.Writeによって書き込みアクセスを許可して開こうとした場合には例外UnauthorizedAccessExceptionがスローされます。

§1.3 FileShare

FileShare列挙体は、FileStreamがファイルを開いた後に同一ファイルに対して許可する操作、つまりファイルを共有する際に許可する操作を指定するためのものです。 FileShare列挙体では、複数の値を組み合わせて指定することができます。

FileShareの値と動作
FileShareの値 意味と同一ファイルに対する制限
FileShare.None 一切の操作を許可しない
FileStreamを閉じるまで同一ファイルを開くことは出来ない
(FileShareを指定しなかった場合のデフォルト)
FileShare.Read 読み込みを許可する
FileStreamを閉じるまで同一ファイルを書き込み可能で開くことは出来ない
FileShare.Write 書き込みを許可する
FileStreamを閉じるまで同一ファイルを読み込み可能で開くことは出来ない
FileShare.ReadWrite 読み込み・書き込みを許可する
FileShare.Delete ファイルの削除を許可する
FileShare.Inheritable ファイルハンドルを子プロセスに継承させる

§1.4 オプションを指定してFileStreamを作成する

FileStreamのコンストラクタでは、次のようにファイルパスFileModeFileAccessFileShareの順で指定します。

FileMode、FileAccess、FileShareを指定してFileStreamを作成する
using System;
using System.IO;

class Sample {
  static void Main()
  {
    // 追記モード・書き込みのみ・共有なしでFileStreamを作成
    using (FileStream stream = new FileStream("sample.dat", FileMode.Append, FileAccess.Write, FileShare.None)) {
      // データの書き込みを行う
      stream.WriteByte(0xff);
    }
  }
}


§1.5 Fileクラスを使ったFileStreamの作成

Fileクラスにはファイルを開いてFileStreamを作成するためのメソッドがいくつか用意されています。 Fileクラスのメソッドを使用するといくつかのオプションの指定を省略することができ、FileStreamの作成をシンプルに記述することができます。 次の例は、FileStreamのコンストラクタとFile.OpenReadメソッドを使って読み込み専用のFileStreamインスタンスを作成する例です。 どちらも同じオプションが指定されたインスタンスが作成されます。

Fileクラスのメソッドを使ってFileStreamを作成する
using System;
using System.IO;

class Sample {
  static void Main()
  {
    // コンストラクタにオプションを指定してFileStreamを作成
    using (FileStream stream = new FileStream("sample.dat", FileMode.Open, FileAccess.Read, FileShare.Read)) {
      // データの読み込み行う
      stream.ReadByte();
    }

    // File.OpenReadメソッドを使ってFileStreamを作成
    using (FileStream stream = File.OpenRead("sample.dat")) {
      // データの読み込み行う
      stream.ReadByte();
    }
  }
}

OpenReadメソッド以外にも、Fileクラスにはファイルを開いてFileStreamを作成するための次のようなメソッドが用意されています。

Fileクラスのメソッドと動作
メソッド 動作 FileStream作成時に指定されるオプション
File.OpenRead 読み込み用に既存のファイルを開く FileMode.Open / FileAccess.Read / FileShare.Read
File.OpenWrite 書き込み用にファイルを作成して開く FileMode.OpenOrCreate / FileAccess.Write / FileShare.None
File.Open FileModeを指定してファイルを開く FileAccess.ReadWrite(FileMode.Appendの場合はFileAccess.Write) / FileShare.None
File.Create 読み書き用にファイルを作成または上書きして開く FileMode.Create / FileAccess.ReadWrite / FileShare.None

§1.6 その他のオプション

FileModeやFileAccessなどの他にも、FileStreamのコンストラクタではバッファサイズやFileOptionsFileSystemRightsFileSecurityなど、より高度なオプションも指定できるようになっています。

§2 ファイル名

Nameプロパティを参照するとFileStreamが現在参照しているファイルの名前を取得することができます。 これは、コンストラクタ等で指定されたパスと同じとなります。 .NET Frameworkでは、相対パスを指定してインスタンスを作成した場合は絶対パスに補完されたファイル名が返されるようです。

Nameプロパティを参照してFileStreamの基となったファイルの名前を取得する
using System;
using System.IO;

class Sample {
  static void Main()
  {
    // 相対パスを指定してFileStreamを作成
    using (FileStream stream = new FileStream("sample.txt", FileMode.Open, FileAccess.Read)) {
      Console.WriteLine(stream.Name);
    }

    // 絶対パスを指定してFileStreamを作成
    using (FileStream stream = new FileStream(@"D:\sample.txt", FileMode.Open, FileAccess.Read)) {
      Console.WriteLine(stream.Name);
    }

    // File.OpenReadメソッドでFileStreamを作成
    using (FileStream stream = File.OpenRead("sample.txt")) {
      Console.WriteLine(stream.Name);
    }
  }
}
実行結果例
D:\sample.txt
D:\sample.txt
D:\sample.txt