bucket-sort logo bucket-sort

プログラミングとインフラエンジニアリングの覚え書き

  • Posts
  • About
  • Contact
  1. Home
  2. All Posts
  3. [C#] ストリームとリーダー/ライターでデータを読み書きする

[C#] ストリームとリーダー/ライターでデータを読み書きする

Jul 16, 2026 C# , .NET bucket-sort

前回は、DirectoryInfo、FileInfo、Directory、File などを使ったファイルシステム操作を見ました。

今回は、ファイル入出力の中心にある ストリーム を扱います。
ストリームは、ファイル、メモリ、ネットワークなど、さまざまな入出力先を「連続したデータの流れ」として扱うための抽象化です。

ストリームとは

Stream は、バイト列を読み書きするための抽象基底クラスです。

代表的な派生型には、次のようなものがあります。

FileStream

ファイルに対してバイト単位で読み書きします。

MemoryStream

メモリ上のバイト列をストリームとして扱います。

NetworkStream

ネットワーク接続をストリームとして扱います。

Stream はバイト列の抽象化です。
テキストを扱う場合は、文字エンコーディングを考慮する必要があるため、StreamReader や StreamWriter を重ねて使うことが多いです。

FileStream でバイトを書き込む

まず、FileStream を使ってバイト列を書き込んでみます。

using System.IO;
using System.Text;

byte[] data = Encoding.UTF8.GetBytes("Hello, stream!");

using FileStream stream = new FileStream(
    "sample.bin",
    FileMode.Create,
    FileAccess.Write);

stream.Write(data, 0, data.Length);

FileMode.Create は、ファイルを新規作成します。
既存ファイルがある場合は上書きします。

FileStream でバイトを読み込む

using System.IO;
using System.Text;

using FileStream stream = new FileStream(
    "sample.bin",
    FileMode.Open,
    FileAccess.Read);

byte[] buffer = new byte[stream.Length];

int read = stream.Read(buffer, 0, buffer.Length);

string text = Encoding.UTF8.GetString(buffer, 0, read);

Console.WriteLine(text);

FileStream はバイト単位で扱うため、文字列へ戻すには Encoding が必要です。

using で確実に閉じる

ファイルやストリームは、使い終わったら閉じる必要があります。
C# では using を使うと、例外が発生しても確実に破棄できます。

using FileStream stream = File.OpenRead("sample.bin");

// stream を使う

ストリームを閉じ忘れると、ファイルがロックされたままになったり、書き込み内容が反映されなかったりすることがあります。

StreamWriter でテキストを書く

テキストを書く場合は、StreamWriter が便利です。

using System.IO;

using StreamWriter writer = new StreamWriter("log.txt", append: false);

writer.WriteLine("アプリケーションを開始しました。");
writer.WriteLine($"時刻: {DateTime.Now}");

追記したい場合は、append: true を指定します。

using StreamWriter writer = new StreamWriter("log.txt", append: true);

writer.WriteLine("追記しました。");

StreamReader でテキストを読む

using System.IO;

using StreamReader reader = new StreamReader("log.txt");

string allText = reader.ReadToEnd();

Console.WriteLine(allText);

1 行ずつ読むこともできます。

using StreamReader reader = new StreamReader("log.txt");

string? line;

while ((line = reader.ReadLine()) != null)
{
    Console.WriteLine(line);
}

大きなファイルでは、ReadToEnd() で全体を一気に読むより、1 行ずつ処理する方がメモリに優しいです。

StreamWriter と StreamReader を直接作る

File.CreateText() や File.OpenText() を使うと、短く書けます。

using StreamWriter writer = File.CreateText("message.txt");

writer.WriteLine("こんにちは");
using StreamReader reader = File.OpenText("message.txt");

Console.WriteLine(reader.ReadToEnd());

内部的にはファイルストリームの上にテキスト用のリーダー/ライターを重ねている、と考えると理解しやすいです。

StringWriter と StringReader

StringWriter と StringReader は、文字列を入出力先として扱います。

using System.IO;

using StringWriter writer = new StringWriter();

writer.WriteLine("1 行目");
writer.WriteLine("2 行目");

string result = writer.ToString();

Console.WriteLine(result);

文字列を読み取り元として扱う例です。

using System.IO;

string source = """
apple
banana
orange
""";

using StringReader reader = new StringReader(source);

string? line;

while ((line = reader.ReadLine()) != null)
{
    Console.WriteLine(line.ToUpperInvariant());
}

StringWriter / StringReader は、ファイルではなく文字列を対象にしたいテストや変換処理で便利です。

BinaryWriter でバイナリデータを書く

BinaryWriter を使うと、数値や文字列をバイナリ形式で書き込めます。

using System.IO;

using FileStream stream = File.Create("person.dat");
using BinaryWriter writer = new BinaryWriter(stream);

writer.Write(1);
writer.Write("Alice");
writer.Write(29);
writer.Write(true);

このファイルはテキストファイルではないため、メモ帳などで見ても読める形式ではありません。
プログラム同士で効率よくやり取りするための形式です。

BinaryReader でバイナリデータを読む

書き込んだ順番と同じ順番で読み取ります。

using System.IO;

using FileStream stream = File.OpenRead("person.dat");
using BinaryReader reader = new BinaryReader(stream);

int id = reader.ReadInt32();
string name = reader.ReadString();
int age = reader.ReadInt32();
bool active = reader.ReadBoolean();

Console.WriteLine($"{id}: {name}, {age}, {active}");

バイナリ読み書きでは、書き込み順序と読み取り順序が契約になります。
途中で項目を増やしたり順番を変えたりすると、古いデータを読めなくなる可能性があります。

File クラスの便利メソッドとの違い

短い処理なら、File.WriteAllText() や File.ReadAllText() が便利です。

File.WriteAllText("note.txt", "hello");
string text = File.ReadAllText("note.txt");

一方、ストリームやリーダー/ライターは、次のような場面で向いています。

  • 大きなファイルを少しずつ読みたい
  • 追記したい
  • バイナリ形式で扱いたい
  • ネットワークやメモリなど、ファイル以外の入出力先も同じ考え方で扱いたい
  • エンコーディングやバッファリングを細かく制御したい

小さなファイルでは便利メソッド、大きな処理や細かい制御ではストリーム、と考えると選びやすくなります。

非同期読み書き

ファイル入出力は時間がかかることがあります。
UI アプリやサーバーアプリでは、非同期 API を使うとスレッドをブロックしにくくなります。

await File.WriteAllTextAsync("async.txt", "非同期で書き込みます。");

string text = await File.ReadAllTextAsync("async.txt");

Console.WriteLine(text);

StreamReader / StreamWriter にも非同期メソッドがあります。

using StreamWriter writer = new StreamWriter("async-log.txt");

await writer.WriteLineAsync("非同期ログ");

大量データや高頻度アクセスでは、同期/非同期の選択が応答性に影響します。

まとめ

ストリームは、バイト列の流れを扱うための抽象化です。
ファイルだけでなく、メモリやネットワークにも同じ考え方を適用できます。

テキストには StreamReader / StreamWriter、文字列には StringReader / StringWriter、バイナリには BinaryReader / BinaryWriter が便利です。
次回は、ファイル変更を監視する方法と、オブジェクトを保存可能な形に変換する考え方へ進みます。

C# .NET Stream FileStream StreamReader StreamWriter BinaryReader BinaryWriter System.IO
← [C#] System.IO でファイルシステムを扱う [C#] ファイル変更の監視とオブジェクト保存の考え方 →

Related Posts

  • [C#] ファイル変更の監視とオブジェクト保存の考え方 Jul 17, 2026
  • [C#] System.IO でファイルシステムを扱う Jul 15, 2026
  • [C#] EF Core でデータベースの準備と初期データを扱う Aug 8, 2026
  • [C#] EF Core とリポジトリでデータ操作を整理する Aug 7, 2026

Table of Contents

  • ストリームとは
    • FileStream
    • MemoryStream
    • NetworkStream
  • FileStream でバイトを書き込む
  • FileStream でバイトを読み込む
  • using で確実に閉じる
  • StreamWriter でテキストを書く
  • StreamReader でテキストを読む
  • StreamWriter と StreamReader を直接作る
  • StringWriter と StringReader
  • BinaryWriter でバイナリデータを書く
  • BinaryReader でバイナリデータを読む
  • File クラスの便利メソッドとの違い
  • 非同期読み書き
  • まとめ

Recent Posts

  • [C#] EF Core でデータベースの準備と初期データを扱う Aug 8, 2026
  • [C#] EF Core とリポジトリでデータ操作を整理する Aug 7, 2026
  • [C#] DbContext の設定と保存処理を拡張する Aug 6, 2026
  • [C#] EF Core のエンティティと表示用モデルを設計する Aug 5, 2026
  • [C#] EF Core を中心にデータアクセス層を分ける Aug 4, 2026

Categories

  • C#150
  • .NET149
  • AWS27
  • Laravel16
  • Entity Framework Core15
  • Linux15
  • MySQL9
  • Apache8
  • PHP8
  • Data Access6
  • DynamoDB6
  • セキュリティ6
  • Nginx5
  • WordPress4
  • インフラ4
  • Hugo3
  • .NET Framework1
  • Aurora1
  • Diagnostics1
  • Filament1

Tags

  • C#
  • .NET
  • AWS
  • Laravel
  • コレクション
  • PHP
  • Entity Framework Core
  • セキュリティ
  • MySQL
  • Linux
  • パフォーマンス
  • Apache
  • LINQ
  • System.Collections.Generic
  • デリゲート
  • リフレクション
  • ADO.NET
  • Code Snippet
  • DynamoDB
  • NoSQL
  • PHP-FPM
  • RDS
  • System.Collections
  • Windows
  • メタデータ
  • メモリ管理
  • CIL
  • DoS
  • Nginx
  • SQL Server
  • WordPress
  • ラムダ式
  • 監視
  • 設計
  • Amazon Linux 2023
  • Delegate
  • Docker
  • IDisposable
  • Ipset
  • Iptables
  • LINQ to Objects
  • OPCache
  • Pointer
  • Reflection
  • System.Collections.Specialized
  • Unsafe
  • Webサーバー
  • アセンブリ
  • インターフェース
  • オブジェクト指向
Powered by Hugo & Explore Theme.