C#ファイルI/O:Stream、FileStream、StreamReader/Writerによる読み書き
ファイルとは、特定の名前とディレクトリパスを持ってディスクに格納されたデータの集合です。ファイルが読み取りまたは書き込みのために開かれると、それはストリームになります。
ストリームは基本的に通信パスを通過するバイトのシーケンスです。主に2種類のストリームがあります:入力ストリームと出力ストリーム。入力ストリームはファイルからデータを読み取るため(読み取り操作)、出力ストリームはファイルに書き込むため(書き込み操作)に使用されます。
C# I/Oクラス
System.IO名前空間には、ファイルの作成・削除、ファイルからの読み取り・書き込み、ファイルのクローズなど、ファイルに関する多数の操作を行うためのクラスが用意されています。
System.IOの主要な非抽象クラス
| No. | クラスと説明 |
|---|---|
| 1 | BinaryReader - バイナリストリームからプリミティブデータを読み取り |
| 2 | BinaryWriter - プリミティブデータをバイナリ形式で書き込み |
| 3 | BufferedStream - バイトストリームの一時記憶 |
| 4 | Directory - ディレクトリ構造の操作を支援 |
| 5 | DirectoryInfo - ディレクトリ操作用(インスタンスメソッド) |
| 6 | DriveInfo - ドライブ情報を提供 |
| 7 | File - ファイル操作を支援(静的メソッド) |
| 8 | FileInfo - ファイル操作用(インスタンスメソッド) |
| 9 | FileStream - ファイルの任意の位置から読み書き |
| 10 | MemoryStream - メモリ内のストリームデータへのランダムアクセス |
| 11 | Path - パス情報の操作 |
| 12 | StreamReader - バイトストリームから文字を読み取り |
| 13 | StreamWriter - ストリームに文字を書き込み |
| 14 | StringReader - 文字列バッファから読み取り |
| 15 | StringWriter - 文字列バッファに書き込み |
FileStreamクラス
System.IO名前空間のFileStreamクラスは、ファイルの読み取り、書き込み、クローズを支援します。このクラスは抽象クラスStreamから派生しています。
FileStreamオブジェクトを作成して、新しいファイルを作成するか既存ファイルを開きます。
FileStream = new FileStream(
,
,
,
);
例:sample.txtを読み取り用に開く
FileStream fs = new FileStream("sample.txt", FileMode.Open, FileAccess.Read, FileShare.Read);
FileMode列挙体
| メンバ | 説明 |
|---|---|
Append | 既存ファイルを開きカーソルを末尾に、またはファイルが存在しない場合は作成 |
Create | 新しいファイルを作成(既存なら上書き) |
CreateNew | 新しいファイルを作成(既存なら例外) |
| 4 | Open - 既存ファイルを開く(存在しない場合例外) |
| 5 | OpenOrCreate - 存在すれば開き、なければ新規作成 |
| 6 | Truncate - 既存ファイルを開きサイズを0に切り詰め |
FileAccess列挙体
Read- 読み取り専用Write- 書き込み専用ReadWrite- 読み書き両方
FileShare列挙体
| メンバ | 説明 |
|---|---|
Inheritable | ファイルハンドルを子プロセスに継承許可 |
None | 現在のファイルの共有を拒否 |
Read | 読み取り用に開くことを許可 |
ReadWrite | 読み書き用に開くことを許可 |
Write | 書き込み用に開くことを許可 |
Delete | 削除を許可 |
FileStream使用例
using System;
using System.IO;
namespace FileIOApplication {
class Program {
static void Main(string[] args) {
FileStream fs = new FileStream("test.dat", FileMode.OpenOrCreate, FileAccess.ReadWrite);
// バイト書き込み
for (int i = 1; i <= 20; i++) {
fs.WriteByte((byte)i);
}
// 位置を先頭に戻して読み取り
fs.Position = 0;
for (int i = 0; i <= 20; i++) {
Console.Write(fs.ReadByte() + " ");
}
fs.Close();
Console.ReadKey();
}
}
}
実行結果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 -1
※ ReadByteはストリーム末尾で-1を返します。
テキストファイルの読み書き(StreamReader/StreamWriter)
テキストファイル操作にはStreamReaderとStreamWriterが便利です。エンコーディングを自動処理します。
テキストファイル書き込み
using (StreamWriter writer = new StreamWriter("output.txt", false, Encoding.UTF8)) {
writer.WriteLine("1行目");
writer.WriteLine("2行目");
writer.Write("改行なし");
}
テキストファイル読み取り(全文)
using (StreamReader reader = new StreamReader("output.txt", Encoding.UTF8)) {
string content = reader.ReadToEnd();
Console.WriteLine(content);
}
テキストファイル読み取り(行ごと)
using (StreamReader reader = new StreamReader("output.txt")) {
string line;
while ((line = reader.ReadLine()) != null) {
Console.WriteLine(line);
}
}
Fileクラスの静的メソッド(簡易操作)
// 全文書き込み
File.WriteAllText("file.txt", "内容", Encoding.UTF8);
File.WriteAllLines("file.txt", new[] { "行1", "行2" });
// 全文読み取り
string text = File.ReadAllText("file.txt");
string[] lines = File.ReadAllLines("file.txt");
// 追記
File.AppendAllText("file.txt", "追加行\n");
File.AppendAllLines("file.txt", new[] { "行3", "行4" });
バイナリファイルの読み書き(BinaryReader/BinaryWriter)
// 書き込み
using (BinaryWriter writer = new BinaryWriter(File.Open("data.bin", FileMode.Create))) {
writer.Write(123); // int
writer.Write(3.14); // double
writer.Write("Hello"); // string
writer.Write(true); // bool
}
// 読み取り(書き込み順序と同じ順序で読む必要あり)
using (BinaryReader reader = new BinaryReader(File.Open("data.bin", FileMode.Open))) {
int i = reader.ReadInt32();
double d = reader.ReadDouble();
string s = reader.ReadString();
bool b = reader.ReadBoolean();
}
ファイルシステム操作(File/Directory/Path)
ファイル操作
// 存在確認
bool exists = File.Exists("file.txt");
// コピー・移動・削除
File.Copy("source.txt", "dest.txt", overwrite: true);
File.Move("old.txt", "new.txt");
File.Delete("temp.txt");
// 情報取得
FileInfo info = new FileInfo("file.txt");
long size = info.Length;
DateTime created = info.CreationTime;
DateTime modified = info.LastWriteTime;
ディレクトリ操作
// 作成・削除・存在確認
Directory.CreateDirectory(@"C:\MyApp\Data");
Directory.Delete(@"C:\MyApp\Data", recursive: true);
bool dirExists = Directory.Exists(@"C:\MyApp\Data");
// 列挙
string[] files = Directory.GetFiles(@"C:\MyApp\Data", "*.txt");
string[] dirs = Directory.GetDirectories(@"C:\MyApp\Data");
string[] all = Directory.GetFileSystemEntries(@"C:\MyApp\Data");
パス操作(Pathクラス)
string path = @"C:\MyApp\Data\file.txt";
string dir = Path.GetDirectoryName(path); // C:\MyApp\Data
string file = Path.GetFileName(path); // file.txt
string ext = Path.GetExtension(path); // .txt
string name = Path.GetFileNameWithoutExtension(path); // file
string combined = Path.Combine(dir, "sub", "new.txt"); // C:\MyApp\Data\sub\new.txt
string full = Path.GetFullPath("..\\file.txt"); // 絶対パスに変換
string temp = Path.GetTempFileName(); // 一時ファイル名生成
非同期I/O(.NET 4.5以降)
UIスレッドブロッキングを避けるため、非同期メソッドを使用します。
// 非同期書き込み
await File.WriteAllTextAsync("file.txt", "内容");
// 非同期読み取り
string content = await File.ReadAllTextAsync("file.txt");
// Streamベース
using (FileStream fs = new FileStream("file.txt", FileMode.Open, FileAccess.Read)) {
byte[] buffer = new byte[1024];
int bytesRead = await fs.ReadAsync(buffer, 0, buffer.Length);
}
エンコーディングの指定
デフォルトはUTF-8(BOMなし)ですが、明示的に指定することを推奨します。
// UTF-8 (BOMなし) - 推奨
var utf8NoBom = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
// Shift_JIS (日本語レガシー)
Encoding.GetEncoding("shift_jis");
ベストプラクティス
- 常に
usingステートメント(またはusing宣言)でリソースを確実に解放する - テキストファイルには
StreamReader/StreamWriter、バイナリにはBinaryReader/BinaryWriterを使用 - 簡易操作には
Fileクラスの静的メソッド(ReadAllText等)を活用 - パス操作は
Pathクラスを使用し、文字列連結でパスを組み立てない - 大容量ファイルはストリームで逐次処理し、メモリに全量読み込まない
- 非同期I/O(
Asyncサフィックスメソッド)を活用してスレッドブロッキングを防ぐ - エンコーディングは明示的に指定(UTF-8推奨)
- 一時ファイルには
Path.GetTempFileName()を使用し、確実にクリーンアップする
C言語
- チタン:主要特性、用途、産業利用
- カスタネット:歴史、職人技、演奏
- 接着剤の歴史、製造、未来:古代アデシブから現代イノベーションへ
- 錫:青銅器時代から現代産業まで - 用途、生産、未来
- ヤスリ工具マスター:金属・木工プロジェクトのための精密切削
- C言語入出力(I/O)マスター:scanf()とprintf()徹底解説
- C言語 ファイル入出力: fopen, fprintf, fread, fseek をマスターする
- C言語ファイルI/O完全ガイド:作成、オープン、管理の実践
- C言語ヘッダーファイルの理解:種類、使い方、ベストプラクティス
- PythonファイルI/O:ファイル操作、読み書き、管理のマスター
- PythonファイルI/O:入出力操作をマスターする