この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
概要
以前、C#(.NET)にはJsonフォーマットを操作するライブラリが完備されなかったため、3rd partyのライブラリはよく使われる気がします(例えばNewtonSoftのJson.NETライブラリ)。最近、C#のデフォルトJson操作ライブラリが使いやすくなっているようですので、できればスタンダードのライブラリを使うべきだと思ってます。
テスト環境
- System : Windows 10 (.NET 5)
- Editor : VSCode
プロジェクトの作成
コマンドラインツール(cmdなど)で下記のコマンドを使って新しいTest
というプロジェクトが作成されます。
dotnet new console -n Test
名前空間を宣言する
これから使う名前空間を先に宣言します。
// Created by default, you can delete this line if you want
using System;
// For File, FileStream, StreamWriter, StreamReader
using System.IO;
// For Json Serialization and Deserialization
using System.Text.Json;
using System.Text.Json.Serialization;
// We use List<T> to contain student information objects
using System.Collections.Generic;
データのクラスを定義する(例:学生個人情報)
// Define a simple student class with basic parameters and constructor
public class Student
{
public string Name { get; set; } = string.Empty;
public string ID { get; set; } = string.Empty;
public int Age { get; set; } = 0;
public Student(string name, string id, int age)
{
Name = name;
ID = id;
Age = age;
}
}
DataをClassにし、JsonSerializerでSerializeする
static void WriteJson()
{
// Create a list container for student information
List<Student> list = new List<Student>();
// Adding student information into list
list.Add(new Student("Sakamoto", "A002", 12));
list.Add(new Student("John", "B013", 15));
list.Add(new Student("Lucy", "C024", 13));
// Make JsonSerializer not to escape non-ASCII character(like Japanese characters).
// If you use English only, the "options" parameter is not needed.
JsonSerializerOptions options = new JsonSerializerOptions() {
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.
Create(System.Text.Unicode.UnicodeRanges.All)};
// Create a new file and get the FileStream in a "using" scope
using (FileStream fileStream = File.Create("StudentInfo.json"))
{
// Create a StreamWriter for the FileStream in a "using" scope
using (StreamWriter writer = new StreamWriter(fileStream, System.Text.Encoding.UTF8))
{
// Write student information into file in a loop
foreach (var student in list)
{
// Serialize student information. If the internal string members are English only, the "options" is not needed.
string str = JsonSerializer.Serialize<Student>(student, options);
writer.WriteLine(str);
}
// Extra explanation :
// It's safer to use a using scope here,
// since both FileStream and StreamWriter expicitly implement "IDisposable" interface,
// which "freeing, releasing, or resetting unmanaged resources" (async version : IAsyncDisposable/DisposeAsync).
//
// The "using" scope helps dealing with Dispose() automatically (even when an exception is thrown),
// because it is translated to try{} finally{x.Dispose()} in compiler.
}
}
}
// Create a list container for student information
List<Student> list = new List<Student>();
// Adding student information into list
list.Add(new Student("Sakamoto", "A002", 12));
list.Add(new Student("John", "B013", 15));
list.Add(new Student("Lucy", "C024", 13));
学生個人情報用のリストを作って、学生情報を作りながらリストに入れる。
JsonSerializerOptions options = new JsonSerializerOptions() {
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.
Create(System.Text.Unicode.UnicodeRanges.All)};
すべての文字をそのまま保存します。
JsonSerializerはASCIIじゃない文字を勝手に\uxxxのようにUnicodeデータとして書き換えます。英語は問題ないですが、日本語などの文字を読めるように保存したい場合はこの行のoptions
が必要です。
using (FileStream fileStream = File.Create("StudentInfo.json"))
学生個人情報のJsonファイルを作成します。
using (StreamWriter writer = new StreamWriter(fileStream, System.Text.Encoding.UTF8))
Jsonファイルにデータを書き込むライター(念のためUTF8
を指定する)を定義します。
string str = JsonSerializer.Serialize<Student>(student, options);
writer.WriteLine(str);
JsonSerializerのドキュメンテーションはこちら:JsonSerializer Class Doc
生徒の情報をSerialize()
し、返した文字列をStreamWriter
経由Jsonファイルに書き込みます。(英語以外の言語文字じゃなければ、先に定義したoptions
をいれなくても大丈夫です。)
JsonSerializerOptionsはいろんなオプションがあるので、ドキュメンテーションを参考してください:JsonSerializerOptions Doc
プロジェクトパスにコマンドラインツールでdotnet run
を実行したら、同じパスにStudentInfo.json
というファイルが作られて、中身はこういう感じ:
{"Name":"Sakamoto","ID":"A002","Age":12}
{"Name":"John","ID":"B013","Age":15}
{"Name":"Lucy","ID":"C024","Age":13}
JsonファイルのデータをJsonSerializerでDeserializeして、プリントする
static void ReadJson()
{
// Open json file and get the FileStream in a "using" scope
using (FileStream fileStream = File.OpenRead("StudentInfo.json"))
{
// Create a StreamReader for the FileStream in a "using" scope
using (StreamReader reader = new StreamReader(fileStream, System.Text.Encoding.UTF8))
{
// Operate in a while loop, which checks if it reaches the end of the stream
while (!reader.EndOfStream)
{
// Deserialize data from line by line and print it
Student student = JsonSerializer.Deserialize<Student>(reader.ReadLine());
Console.WriteLine($"Name:{student.Name}, ID:{student.ID}, Age:{student.Age}");
}
}
}
}
using (FileStream fileStream = File.OpenRead("StudentInfo.json"))
先ほど作ったStudentInfo.json
を開いて、それのFileStream
をもらいます。
using (StreamReader reader = new StreamReader(fileStream, System.Text.Encoding.UTF8))
Jsonファイルにデータを読みだすリーダー(念のためUTF8
を指定する)を定義します。
while (!reader.EndOfStream)
読み終わったかどうかをループでチェックします。
Student student = JsonSerializer.Deserialize<Student>(reader.ReadLine());
Console.WriteLine($"Name:{student.Name}, ID:{student.ID}, Age:{student.Age}");
最後は、DeserializeしたデータをStudent
クラスオブジェクトに返して、中身をプリントします。プリントした結果はこんな感じ:
Name:Sakamoto, ID:A002, Age:12
Name:John, ID:B013, Age:15
Name:Lucy, ID:C024, Age:13
まとめ
JsonSerializer
クラスを使って、データを簡単に整えたり、操作できます。StreamWriter
やStreamReader
なども活用し、やれることが多くなる気がします。そしてJsonSerializerOptions
でカスタマイズできるオプションも多いし、更に自由度がありそうです。C#(.NET)でJsonSerializerを使って普通のデータ、I/O処理などは楽だと思います。