CodeGym /コース /C# SELF /テキストファイルの書き込み: StreamWrite...

テキストファイルの書き込み: StreamWriter

C# SELF
レベル 36 , レッスン 3
使用可能

1. はじめに

StreamWriterは、.NETの名前空間System.IOの中でも、テキストデータをストリーム経由でファイルに書き込むのに超便利なクラスだよ。

なんでいきなりFileStreamでやっちゃダメなの?
FileStreamはバイト単位でしか操作できないんだ。文字列を書き込もうとすると、自分でテキストをバイトに変換したり、エンコーディングを気にしたりしなきゃいけない(そのうち絶対StreamWriterに戻りたくなるよ)。
StreamWriterなら、そういう面倒は全部おまかせ。文字列を渡せば、必要なバイトにしてファイルに書いてくれる。

主なメリット:

  • バイト変換とか気にせずに文字列を書ける。
  • 1行ずつテキストを書き込むメソッドがある。
  • バッファやエンコーディングの制御もできる(これも後でやるよ)。

超シンプルな例

using System.IO;

string path = "output.txt";

using (StreamWriter writer = new StreamWriter(path))
{
    writer.WriteLine("こんにちは、世界!");
    writer.WriteLine("これは2行目だよ。");
}
// usingブロックを抜けるとStreamWriterがちゃんとファイルを解放してくれる。

ここで何が起きてる?

  • 書き込み用にファイルを開く(ファイルがなければ作られる)。
  • 各行はファイルの別々の行として書き込まれる(WriteLineメソッド)。
  • usingブロックの後は自動でファイルが閉じられる。エラーがあっても大丈夫。

このプログラムを実行した後でoutput.txtを開くと、ちゃんと2行のテキストが入ってるはず。

大事なポイント

もしファイルがすでに存在してたら、最初から上書きされるよ!中身は全部消えるから注意。大事な論文とか、唯一の領収書とかはこういうファイルに入れないでね。

2. データをストリームに書き込む

StreamWriterの主なメソッド

メソッド 説明
Write(string)
改行なしで文字列を書き込む
WriteLine(string)
改行付きで文字列を書き込む
Flush()
バッファを強制的にファイルに書き込む(手動でやることはあんまりない)
Close()
/
Dispose()
ストリームを閉じてリソース解放(usingがやってくれる)
BaseStream
ベースのストリーム(例: FileStream)にアクセスできる

Write()メソッド

改行せずにデータを書き込む。続けて書くと同じ行にどんどん追加されるよ。

WriteLine()メソッド

自動で改行コードを追加して書き込む(Windowsなら\r\n、Unix系なら\n)。
毎回Enterキーを押してる感じ。

Write()WriteLine()の違いデモ

using (var writer = new StreamWriter("example.txt"))
{
    writer.Write("最初の ");
    writer.Write("段落。");
    writer.WriteLine("行を追加して、Enter!");
    writer.Write("2番目の段落。");
}

これでexample.txtはこんな感じになるよ:

最初の 段落。行を追加して、Enter!
2番目の段落。

3. エンコーディングの扱い

デフォルトでStreamWriterをパラメータなしで作ると、UTF-8BOM付き(Byte Order Mark)になるよ。

今どきはこれでOKだけど、古いソフトやインポート用データの互換性のためにエンコーディングを指定したい場合もある。

エンコーディングの指定方法

// Windows-1251(古いシステム用キリル文字)のファイルを書き込む
using (var writer = new StreamWriter("cyrillic.txt", false, System.Text.Encoding.GetEncoding("windows-1251")))
{
    writer.WriteLine("こんにちは、キリル世界!");
}

大事なポイント:
エンコーディングはシステムでサポートされてる必要があるよ。不安ならUTF-8を使おう。

4. コンストラクタの追加パラメータ

StreamWriterの中身をちょっと覗いてみよう:

public StreamWriter(
    string path,              // ファイルのパス
    bool append = false,      // ファイルの末尾に追記する?
    Encoding encoding = null, // エンコーディング
    int bufferSize = 1024     // バッファサイズ(バイト単位)
)
  • appendfalse(デフォルト)なら上書きtrueなら末尾に追加。
  • encoding — 使うエンコーディング。
  • bufferSize — 大量データのときに効く内部バッファサイズ。

例: 同じファイルに追記する

// ファイルは上書きじゃなくて追記される
using (var writer = new StreamWriter("log.txt", append: true))
{
    writer.WriteLine(DateTime.Now + " -- 新しいイベント");
}

5. 便利なポイント

追記と上書きのとき何が起きる?

モード 何をする? ファイルの結果
append: false 全部きれいに上書き 古いデータは消える
append: true 新しい行を末尾に追加 古い行は残る

ヒント: 追記モード(append: true)はログとか履歴を残したいときに超便利!

StreamWriterと大量データ

  • StreamWriterは書き込みをバッファリングしてる。実際にファイルに書かれるのはちょっと後。でもストリームを閉じる(またはFlush()を呼ぶ)と確実にディスクに保存される。
  • WriteLineで1行ずつ書くのはめっちゃ効率的。JSON、CSV、XMLみたいな複雑なフォーマットは専用ライブラリを使うか、カンマやクォートのエスケープに気をつけてね。

正しい終了方法とリソース解放

正しいやり方: いつもusingを使おう!
これで、たとえ例外(例えばディスクが急に「いっぱい」になったり、他のプログラムがファイルをロックしたりしても)でも、ファイルはちゃんと閉じられる。


flowchart TD
    A[StreamWriterの作成] --> B[ファイル操作]
    B --> C{例外発生?}
    C -- はい --> D[Disposeが呼ばれる]
    C -- いいえ --> D
    D --> E[ファイルは確実に閉じられる]
図: usingはエラーがあってもファイルを確実に閉じてくれる

6. 実践例

この講座の中で、簡単な本の管理プログラムを作るとして、新しい本をファイルに書き込む機能を追加してみよう。

例: 新しい本を別ファイルに保存する

using System;
using System.IO;

class Program
{
    static void Main()
    {
        Console.WriteLine("本のタイトルを入力してね:");
        string bookTitle = Console.ReadLine();

        Console.WriteLine("著者を入力してね:");
        string author = Console.ReadLine();

        string path = "books.txt";
        using (var writer = new StreamWriter(path, append: true))
        {
            writer.WriteLine($"{bookTitle};{author}");
            // CSV形式: 1行が1冊、セミコロン区切り
        }

        Console.WriteLine("本をファイルに保存したよ!");
    }
}

何冊か続けて追加してみて。books.txtには前の行を消さずにどんどん追加されるよ。こういう動きはログや履歴管理に便利。将来Enterprise開発者になったときの監査システムにも使えるかもね。

7. ファイル書き込みでよくあるミスを避けるには

初心者がよくハマるポイントはこんな感じ:

ファイルが閉じられてなくて他のプロセスにロックされる。原因はusingを忘れたこと。

たくさん書いたのにファイルが空っぽ:Flush()やストリームのクローズを忘れた(usingなら自動でやってくれる)。

追記したつもりが上書きしちゃった:append: trueを指定し忘れた。

エンコーディングの問題:ファイルがメモ帳で「文字化け」するのは、エンコーディングが違うか、他のソフトがUTF-8に対応してない。

UnauthorizedAccessExceptionDirectoryNotFoundException:保存先に権限がないか、存在しないフォルダに書こうとしてる。パスと権限を確認しよう。

エラー "file is used by another process":ファイルを開いたまま閉じてないか、他の誰かが同時に書き込もうとしてる。

2
タスク
C# SELF, レベル 36, レッスン 3
ロック未解除
ファイルへの書き込みと追記
ファイルへの書き込みと追記
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION