【C#】C#でファイルを読み書きする方法まとめ

地味にいくつかやり方があって迷う、C#におけるファイル読み書き方法をまとめました。

バイト配列を読み書きするFileStream

まず、バイト配列を読み書きするにはFileStreamクラスを使います。
読み込みは下記のようにRead()を呼びます。

using (var fs = new System.IO.FileStream(@"C:\Users\Desktop\test", System.IO.FileMode.Open)) {
    try
    {
        var bs = new byte[fs.Length];
        fs.Read(bs, 0, bs.Length);
    }
    catch (System.Exception e)
    {
    }
    finally
    {
        if (fs != null) {
            fs.Close();
        }
    }
}

ファイルに書き込むにはWrite()メソッドを使います。

using (var fs = new System.IO.FileStream(@"C:\Users\Desktop\test.txt", System.IO.FileMode.Create, System.IO.FileAccess.Write)) {
    try
    {
        var bs = new byte[] { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 };
        fs.Write(bs, 0, bs.Length);
    }
    catch (System.Exception e)
    {
    }
    finally
    {
        if (fs != null) {
            fs.Close();
        }
    }
}

文字列を読み書きするStreamReader/StreamWriter

次に文字列をファイルに読み書きしてみます。
文字列を読み込むにはStreamReaderクラスを使います。

using (var fs = new System.IO.StreamReader(@"C:\Users\Desktop\test.txt", System.Text.Encoding.GetEncoding("shift_jis"))) {
    try
    {
        var result = fs.ReadToEnd();
    }
    catch (System.Exception e)
    {
    }
    finally
    {
        if (fs != null) {
            fs.Close();
        }
    }
}

文字列を書き込むにはStreamWriterクラスを使います。

using (var fs = new System.IO.StreamWriter(@"C:\Users\Desktop\test.txt", true, System.Text.Encoding.GetEncoding("shift_jis"))) {
    try
    {
        fs.Write("あいうえお");
    }
    catch (System.Exception e)
    {
    }
    finally
    {
        if (fs != null) {
            fs.Close();
        }
    }
}

簡単に読み書きするならFileクラスがおすすめ

上述のようなファイル読み書きを簡潔に記述できるクラスとして、Fileクラスがあります。

System.IO.File.ReadAllBytes(@"Path\To\File");
System.IO.File.WriteAllBytes(@"Path\To\File", new byte[] { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 });

System.IO.File.ReadAllText(@"Path\To\File");
System.IO.File.WriteAllText(@"Path\To\File", "contents");

これはStreamで行う処理をラップしたもので、細かい制御はできないものの、
usingしなくても確実にファイルを閉じてくれたりします。

お手軽にファイル操作ができる便利なメソッドという位置づけです。

stackoverflow.com

非同期で読むにはReadAsyncを使う

さてこれまでの方法ではファイル読み書きは同期的に行われます。
つまり巨大なファイルを読んだ時にはメインスレッドがブロックされてしまいます。

FileStream.ReadAsync()を使うと非同期な読み込みを実現できます。

using (var fs = new System.IO.FileStream(@"C:\Users\Desktop\test.txt", System.IO.FileMode.Open)) {;
    try
    {
        var bs = new byte[fs.Length];
        await fs.ReadAsync(bs, 0, bs.Length);
    }
    catch (System.Exception e)
    {
    }
    finally
    {
        if (fs != null) {
            fs.Close();
        }
    }
}

下記のように書けばメインスレッド以外で処理が行われていることが確認できます。

await fs.ReadAsync(bs, 0, bs.Length).ContinueWith(_ => System.Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId));

参考

dobon.net

softmedia.sakura.ne.jp

stackoverflow.com