C#でバイナリファイルに書き込む

C#でバイナリファイルに書き込むには System.IO.FileStream クラスと System.IO.BinaryWriter クラスを使います。

ここでは FileStream クラスと BinaryWriter クラスの基本的な使い方についてまとめてみます。

FileStreamとBinaryWriterの役割

FileStreamクラス

ファイル名を指定してファイルの中身を読み書きする為のクラスです。

データは 1byte づつもしくは byte 配列で読み書きする為のメソッドがありますが、それだけでは不便なので BinaryWriter クラスと合わせて使う事でより手軽にバイナリファイルの書き込みが行えるようになります。

BinaryWrietrクラス

Stream クラスから、intdouble などの型単位でデータを読み込むためのクラスです。

使用する Stream クラスはコンストラクタでを指定します。

ファイルからデータを読み込むには Stream クラスから派生した FileStreamクラスを指定します。

ファイルを開く

FileStream オブジェクトを生成すると、ファイルがオープンされて内容を読み込める状態になります。

 

読み込みたいファイルの名前はコンストラクタの引数に渡します。

この他コンストラクタには FileMode などを指定する事が出来ます。

 

FileMode

  • FileMode.CreateNew   ・・・新しいファイルを作成(ファイルが存在する場合Truncatと同じ)
  • FileMode.Create     ・・・新しいファイルを作成(ファイルが存在する場合例外がスロー)
  • FileMode.Open      ・・・ファイルを開く(ファイルが存在しない場合例外がスロー)
  • FileMode.OpenOrCreate  ・・・ファイルが存在する場合は開き、存在しない場合は新しいファイルを作成
  • FileMode.Truncate     ・・・ファイルは開かれると、サイズが 0 バイトになるように切り詰め
  • FileMode.Append     ・・・ファイルが存在する場合は開き、ファイルの末尾をシーク

 

 

生成したFileStreamを使って BinaryWriter オブジェクトを生成します。

 

 

    var fileName = @"c:\test.dat";
    var writer = new BinaryWriter(new FileStream(fileName, FileMode.Create));

ファイルを読む

BinaryWriter クラスには様々な型でデータを書き込むメソッドが用意されています。

 

  • Write(Byte[], int, int)  ・・・指定されたバイト数をバイト配列に書き込み
  • Write(SByte)      ・・・1 バイト符号付きを書き込み
  • Write(Int16)         ・・・2 バイト符号付き整数を書き込み
  • Write(Int32)        ・・・4 バイト符号付き整数を書き込み
  • Write(Int64)        ・・・8 バイト符号付き整数を書き込み
  • Write(Byte)        ・・・1 バイト符号なし整数を書き込み
  • Write(UInt16)       ・・・2 バイト符号なし整数を書き込み
  • Write(UInt32)       ・・・4 バイト符号なし整数を書き込み
  • Write(UInt64)       ・・・8 バイト符号なし整数を書き込み
  • Write(Single)        ・・・4 バイト浮動小数点値を書き込み
  • Write(Double)       ・・・8 バイト浮動小数点値を書き込み

 

ファイルを閉じる

ファイルは開いたら必ず閉じる必要があります。

ファイルを閉じるには StreamWriter クラスの Close() メソッドを呼び出します。

Close は finally で

ファイルの読み込み中に例外が発生する可能性がある事を必ず考慮してコードを書きましょう。

try ... finally ステートメントの finally ブロックで Close() を呼び出す事で例外発生時にも対応したコードを書くことが出来ます。

    var fileName = @"c:\test.dat";
    var writer = new BinaryWriter(new FileStream(fileName, FileMode.Create));
    try
    {
        //書き込む処理
        writer.Write((Int32)100);
        writer.Write((Int16)100);
        writer.Write((Double)100.0);
       :
       :

    }
    finally
    {
        writer.Close();
    }

Close の代わりに using を使う

StreamWriter クラスは IDisposable インターフェースをもっているので、Close() メソッドのかわりに using 構文を使う事も出来ます。

 

下記の例は、上の try … finally を使ったコードと全く同じ動きをします。

using ブロックを抜けた時点で(例外が起きる起きないにかかわらず)IDispposableインターフェースの Dispose() メソッドが呼ばれます。この Dispose() でファイルを閉じる処理が行われます。

    var fileName = @"c:\test.dat";
    using (var writer = new BinaryWriter(new FileStream(fileName, FileMode.Create)))
    {
        //書き込む処理
        writer.Write((Int32)100);
        writer.Write((Int16)100);
        writer.Write((Double)100.0);
       :
       :

    }