げぼげぼメモ

自分用いろいろメモです

C# テキストファイルを読み込んでjson形式で出力

適当なフォーマットのテキストデータを読み込んでjson形式で出力します。
ログに出力したデータをDatatablesで表示できるような形にするイメージです。

data.txt

[Player] X[1] Y[2] Type[0]
[Enemy] Level[1] Name[xxx] Color[Red]
----------------------------------
[Player] X[2] Y[2] Type[1]
[Player] X[1] Y[3] Type[2]
[Enemy] Level[4] Name[yyy] Color[Green]
----------------------------------
[Player] X[3] Y[3] Type[3]
[Enemy] Level[3] Name[zzz] Color[Blue]
[Enemy] Level[1] Name[www] Color[Black]

最初の[Player]や[Enemy]がデータの種類、Level[...]などがパラメータ名、[...]内の値がデータです。
データ以外の行も含まれることを想定しています。

データの種類ごとにファイル別に出力します。

using System;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace DataViewer.Models
{
    public class PlayerList
    {
        [JsonProperty("data")]
        public List<Player> Players { get; set; } = new List<Player>();
    }
    public class EnemyList
    {
        [JsonProperty("data")]
        public List<Enemy> Enemies { get; set; } = new List<Enemy>();
    }

    public class Player
    {
        public int X { get; set; } = 0;
        public int Y { get; set; } = 0;
        public int Type { get; set; } = 0;

    }

    public class Enemy
    {
        public int Level { get; set; } = 0;
        public string Name { get; set; } = "";
        public string Color { get; set; } = "";
    }

    public class DataConverter
    {
        private string inputFilePath = "";
        private PlayerList playerList = new PlayerList();
        private EnemyList enemyList = new EnemyList();

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="filePath">入力ファイルパス</param>
        public DataConverter(string filePath)
        {
            inputFilePath = filePath;
            ReadData();
            OutputPlayer();
            OutputEnemy();
        }

        /// <summary>
        /// テキストファイル読み込み
        /// </summary>
        private void ReadData()
        {
            StreamReader sr = new StreamReader("data.txt", Encoding.GetEncoding("Shift_JIS"));

            char[] delim = { '[', ']' }; // splitの分割用
            while (sr.EndOfStream == false)
            {
                string line = sr.ReadLine();
                string[] data = line.Split(delim);
                int dataSize = data.Count();
                if (dataSize < 2) continue; // データ以外の行はとばす


                if (data[1] == "Player" && dataSize >= 7)
                {
                    // [Player] X[1] Y[2] Type[3]
                    // data[0] = "", data[1] = "Player", data[2] = " X", ...
                    int x = Int32.Parse(data[3]);
                    int y = Int32.Parse(data[5]);
                    int type = Int32.Parse(data[7]);
                    playerList.Players.Add(new Player { X = x, Y = y, Type = type });
                }
                else if (data[1] == "Enemy" && dataSize >= 7)
                {
                    // [Enemy] Level[1] Name[aaa] Color[Red]
                    // data[0] = "", data[1] = "Enemy", data[2] = " Level", ...
                    int level = Int32.Parse(data[3]);
                    string name = data[5];
                    string color = data[7];
                    enemyList.Enemies.Add(new Enemy { Level = level, Name = name, Color = color });
                }
            }
            sr.Close();
        }

        /// <summary>
        /// プレイヤーデータをjson形式で出力
        /// </summary>
        private void OutputPlayer()
        {
            string jsonStr = JsonConvert.SerializeObject(playerList, Formatting.Indented);
            File.WriteAllText(@"player.json", jsonStr);
        }

        /// <summary>
        /// 敵データをjson形式で出力
        /// </summary>
        private void OutputEnemy()
        {
            string jsonStr = JsonConvert.SerializeObject(enemyList, Formatting.Indented);
            File.WriteAllText(@"enemy.json", jsonStr);
        }        
    }
}

Json.NETを使用しています。Nugetでの追加が必要です。


Datatablesで使用できる形に合わせたので無理矢理感がすごいですが、表示だけのものなので動けばおっけーです。


参考
C# による JSON 相互変換 (Json.NET 利用) - clock-up-blog