C#でJSON・XMLファイルを読み書きする方法を完全解説!初心者向けの簡単ガイド
生徒
「C#を使って、ゲームのセーブデータや設定ファイルを保存したいのですが、どうすればいいですか?」
先生
「それなら、JSONやXMLというデータ形式を使ってファイルを読み書きするのが一般的ですね。C#には便利な機能がたくさんありますよ。」
生徒
「JSONとかXMLって難しそうですね。プログラミング初心者でも簡単に扱えるのでしょうか?」
先生
「大丈夫です。基本さえ押さえれば、驚くほど短いコードでデータの保存や読み込みができるようになります。さっそく学んでいきましょう!」
1. JSONとXMLとは何かを学ぼう
プログラミングの世界では、情報を整理して保存するための形式がいくつかあります。その中でも特によく使われるのがJSON(ジェイソン)とXML(エックスエムエル)です。
JSONは「JavaScript Object Notation」の略で、人間が見てもコンピュータが処理しても分かりやすいのが特徴です。最近のウェブ開発やスマートフォンのアプリでは、このJSONが主流になっています。見た目は辞書のように、名前と値がペアになっています。
一方、XMLは「Extensible Markup Language」の略で、HTMLのようにタグを使ってデータを囲む形式です。昔から多くのシステムで使われており、データの構造を厳密に定義したい場合に適しています。
これらの形式を使う最大のメリットは、プログラムを終了してもデータを保存しておけることです。これをデータの永続化と呼びます。例えば、ゲームのハイスコアや、ユーザーのプロフィール設定などをファイルとして残しておくことができます。
2. C#でJSONを扱うための準備
C#でJSONを扱うには、標準で用意されているSystem.Text.Jsonという名前空間(機能の集まり)を使用します。以前は別のライブラリをインストールする必要がありましたが、現在は最新のC#であれば最初から入っています。
JSON操作の基本は、シリアル化(シリアライズ)と逆シリアル化(デシリアライズ)という二つの言葉を覚えることから始まります。名前は難しそうですが、意味はとてもシンプルです。
- シリアル化:プログラム上のデータ(オブジェクト)を、保存可能なテキスト形式(JSON)に変換すること。
- 逆シリアル化:保存されたテキスト形式(JSON)を、再びプログラムで使えるデータ(オブジェクト)に戻すこと。
この変換を行うことで、メモリ上にある一時的なデータをファイルという形に変えて保存できるようになります。
3. データをJSONとして保存する基本的な方法
まずは、プログラムの中にあるデータをJSON形式のテキストに変換して、ファイルに書き込む方法を見ていきましょう。ここでは、ユーザーの名前と年齢を保存する簡単なプログラムを作成します。
C#では、File.WriteAllTextというメソッドを使うと、一行でテキストファイルを作成して中身を書き込むことができます。これは非常に便利な命令です。
using System;
using System.IO;
using System.Text.Json;
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}
class Program
{
static void Main()
{
// 保存したいデータを作成
User myUser = new User { Name = "田中太郎", Age = 25 };
// データをJSON形式の文字列に変換(シリアル化)
string jsonString = JsonSerializer.Serialize(myUser);
// ファイルに保存する
File.WriteAllText("user.json", jsonString);
Console.WriteLine("JSONファイルを作成しました!");
Console.WriteLine("中身: " + jsonString);
}
}
JSONファイルを作成しました!
中身: {"Name":"\u7530\u4E2D\u592A\u90CE","Age":25}
上記のコードを実行すると、実行ファイルと同じ場所に「user.json」というファイルが作られます。日本語が少し特殊な記号に見えることがありますが、これはコンピュータが正しく処理するための仕組みですので安心してください。
4. JSONファイルを読み込んでデータを使う方法
次に、保存したJSONファイルを読み取って、プログラムの中で使えるように戻す方法を解説します。ここで登場するのがFile.ReadAllTextです。この命令は、指定したファイルの内容をすべてテキストとして読み込みます。
読み込んだテキストをJsonSerializer.Deserializeに渡すことで、元のクラスの形に戻すことができます。これで、以前保存した設定やスコアを再利用できるようになります。
using System;
using System.IO;
using System.Text.Json;
class Program
{
static void Main()
{
// ファイルからテキストをすべて読み込む
string fileName = "user.json";
if (File.Exists(fileName))
{
string jsonString = File.ReadAllText(fileName);
// JSONをクラスのオブジェクトに変換(逆シリアル化)
User loadedUser = JsonSerializer.Deserialize<User>(jsonString);
Console.WriteLine("データを読み込みました!");
Console.WriteLine("名前: " + loadedUser.Name);
Console.WriteLine("年齢: " + loadedUser.Age);
}
else
{
Console.WriteLine("ファイルが見つかりません。");
}
}
}
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}
データを読み込みました!
名前: 田中太郎
年齢: 25
File.Existsという命令を使って、ファイルが存在するかどうかを事前に確認するのがプログラミングのコツです。ファイルがないのに読み込もうとするとエラーが発生してしまうからです。
5. JSONを読みやすく保存する設定
デフォルトの設定でJSONを保存すると、改行がなくて人間には少し読みづらい形式になります。設定ファイルを直接メモ帳などで開いて編集したい場合は、見やすく整形して保存するのがおすすめです。
JsonSerializerOptionsというクラスを使うことで、インデント(字下げ)を追加したり、日本語をそのまま表示させたりといった細かい調整が可能です。特にWriteIndented = trueという設定はよく使われます。
using System;
using System.Text.Json;
using System.Text.Encodings.Web;
using System.Text.Unicode;
class Program
{
static void Main()
{
var data = new { Item = "リンゴ", Price = 150 };
// 見やすくするための設定
var options = new JsonSerializerOptions
{
WriteIndented = true, // 改行と空白を入れる
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All) // 日本語をそのまま表示
};
string prettyJson = JsonSerializer.Serialize(data, options);
Console.WriteLine(prettyJson);
}
}
{
"Item": "リンゴ",
"Price": 150
}
このように設定を加えるだけで、中身がぐっと分かりやすくなります。開発中のデバッグ(間違い探し)でも非常に役立つテクニックです。
6. XMLファイルを読み書きする方法
JSONだけでなく、XMLの扱い方も知っておくと便利です。C#でXMLを扱うには、System.Xml.Serializationという名前空間にあるXmlSerializerというクラスを使います。
XMLはJSONよりも記述量が増えますが、階層構造がはっきりしており、古くからの業務システムなどで多用されています。基本的な考え方はJSONと同じで、シリアル化と逆シリアル化の手順を踏みます。
using System;
using System.IO;
using System.Xml.Serialization;
public class GameData
{
public int Level { get; set; }
public string StageName { get; set; }
}
class Program
{
static void Main()
{
GameData data = new GameData { Level = 10, StageName = "秘密の森" };
XmlSerializer serializer = new XmlSerializer(typeof(GameData));
// 書き込み
using (StreamWriter sw = new StreamWriter("save.xml"))
{
serializer.Serialize(sw, data);
}
Console.WriteLine("XMLファイルを保存しました。");
// 読み込み
using (StreamReader sr = new StreamReader("save.xml"))
{
GameData loadedData = (GameData)serializer.Deserialize(sr);
Console.WriteLine($"レベル: {loadedData.Level}, ステージ: {loadedData.StageName}");
}
}
}
XMLファイルを保存しました。
レベル: 10, ステージ: 秘密の森
XMLの場合は、StreamWriterやStreamReaderといった「ストリーム」という道具を使ってファイルを操作するのが一般的です。ストリームとは、データの流れを扱うための土管のようなものだと考えてください。
7. パスとディレクトリの操作
ファイルを読み書きする際、ファイル名だけを指定すると、プログラムが動いている場所(カレントディレクトリ)にファイルが作られます。しかし、実際には「Documentsフォルダ」や「AppDataフォルダ」に保存したい場合が多いでしょう。
そこで重要になるのがパス(Path)の操作です。パスとは、ファイルがコンピュータのどこにあるかを示す住所のようなものです。C#のPath.Combineという機能を使うと、フォルダ名とファイル名を安全につなげることができます。
また、保存先のフォルダが存在しない場合に備えて、Directory.CreateDirectoryを使ってフォルダを自動作成する処理もよく書かれます。これらを組み合わせることで、エラーに強い堅牢なプログラムになります。
8. エラーが起きた時の対処法(例外処理)
ファイル操作には、常に「失敗」の可能性がつきまといます。例えば、ファイルが読み取り専用になっていたり、空き容量が足りなかったり、他のソフトがそのファイルを開いていたりする場合です。
初心者がよく陥るミスは、ファイルがある前提でコードを書いてしまい、いざという時にアプリが強制終了してしまうことです。これを防ぐために、try-catchという仕組みを使って、エラーが起きた時の動きを決めておきます。
具体的には、「ファイルを読み込もうとしてエラーが出たら、画面にメッセージを出して処理を中断する」といった書き方をします。これにより、ユーザーにとって親切なアプリケーションを作ることができます。ファイル操作とエラー処理は、セットで覚えるのがプロの基本です。
9. リストや配列をJSONに保存する
これまでは一つのデータだけを扱ってきましたが、実際には「複数のユーザー情報」や「アイテムリスト」など、たくさんのデータをまとめて保存したいことが多いはずです。C#のListや配列を使えば、これらも簡単にJSONに変換できます。
リストをシリアル化すると、JSON上では[](角括弧)で囲まれた形式になります。これは配列を表しており、複数のデータが並んでいることを意味します。読み込む際も、List<クラス名>という型を指定するだけで、自動的にリスト構造に戻してくれます。
この仕組みを使えば、どれだけデータが増えても、一つのファイルにまとめて整理して保存できるため、非常に効率的です。データベースを使うほどではないけれど、まとまった情報を管理したいという場面で最適な手法と言えるでしょう。