いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

FileHelpers入門記-02 (固定長ファイルをマッピング)(Fixed, 固定長, Length)


次は、固定長データのマッピングにトライ。


やり方はデリミタデータの場合とほぼ同じです。
つまり、マッピングクラスを適切に定義できれば勝ちです。


今回のサンプルデータは以下のようなデータです。(Persons.datとします。)

__100gsf_zero1__30090-0000-11111979/01/01_00:00:00
__200gsf_zero2____090-0000-11121979/01/02_00:00:00
__300gsf_zero3__32090-0000-11131979/01/03_00:00:00
__400gsf_zero4__33090-0000-11141979/01/04_00:00:00
__500gsf_zero5__34090-0000-11151979/01/05_00:00:00

"_"は半角スペースを表します。上記のデータは以下の形式を持つ固定長です。

  • 1列目:数値で、幅5桁。右詰め。
  • 2列目:文字列で、幅10桁。左詰め。
  • 3列目:数値で、幅3桁。右詰め。空データ許容。
  • 4列目:文字列で、幅13桁。
  • 5列目:日付で、幅19桁。


以下、マッピングクラスです。

    [FixedLengthRecord()]
    public class Person {

        [FieldFixedLength(5)]
        [FieldTrim(TrimMode.Left)]
        public int Id;

        [FieldFixedLength(10)]
        [FieldTrim(TrimMode.Right)]
        public string Name;

        [FieldFixedLength(3)]
        [FieldTrim(TrimMode.Left)]
        [FieldNullValue(-1)]
        public int Age;

        [FieldFixedLength(13)]
        public string Tel;

        [FieldFixedLength(19)]
        [FieldConverter(ConverterKind.Date, "yyyy/MM/dd hh:mm:ss")]
        public DateTime Birthday;

        public override int GetHashCode() {
            return this.ToString().GetHashCode();
        }

        public override bool Equals(object obj) {
            if (base.Equals(obj)) {
                return true;
            }

            return (this.ToString() == ((Person)obj).ToString());
        }
        public override string ToString() {
            return string.Format("Id={0},Name={1},Age={2},Tel={3},BirthDay={4}", Id, Name, Age, Tel, Birthday);
        }
    }

固定長の場合は、クラスにFixedLengthRecord属性を付加します。
後は、前回と同様にフィールドを定義していくだけです。
桁数を表すには

FieldFixedLength

属性を利用します。


また、固定長の場合は半角スペースで足りない桁を埋める事が多いです。
その場合は以下の属性を付加します。

FieldTrim

この属性はTrimModeを指定できるので、Trimしたい方向を指定します。



後は、エンジンを構築して利用するだけです。
といっても、実はエンジン周りのコードは, 実は区切り文字の場合は同じものになります。
以下、全体ソースです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using FileHelpers;

namespace FileHelpersSamples2 {

    class Program {

        const string DATA_FILE = @".\Persons.dat";
        const string DATA_FILE2 = @".\Persons2.dat";
        const string DATA_FILE3 = @".\Persons3.dat";

        public void Execute() {
            //
            // エンジンを構築.
            //
            FileHelperEngine<Person> engine = new FileHelperEngine<Person>(Encoding.GetEncoding("sjis"));

            //
            // データ読み取り.
            //
            Person[] persons = engine.ReadFile(DATA_FILE);
            persons.ToList().ForEach(Console.WriteLine);

            //
            // データ書き込み. (同じデータ)
            //
            engine.WriteFile(DATA_FILE2, persons);

            //
            // 同じデータが書き込めているか?
            //
            engine = new FileHelperEngine<Person>(Encoding.GetEncoding("sjis"));
            Console.WriteLine("同じデータ?⇒{0}", persons.SequenceEqual(engine.ReadFile(DATA_FILE2)));

            //
            // データを一部改変し、書き込み.
            //
            persons.Take(2).ToList().ForEach((p) => { p.Age += 100; });
            persons.ToList().ForEach(Console.WriteLine);

            engine.WriteFile(DATA_FILE3, persons);

            //
            // 違うデータとなっているか?
            //
            Console.WriteLine("同じデータ?⇒{0}", engine.ReadFile(DATA_FILE).SequenceEqual(engine.ReadFile(DATA_FILE3)));
        }

        static void Main(string[] args) {

            (new Program()).Execute();

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }

    [FixedLengthRecord()]
    public class Person {

        [FieldFixedLength(5)]
        [FieldTrim(TrimMode.Left)]
        public int Id;

        [FieldFixedLength(10)]
        [FieldTrim(TrimMode.Right)]
        public string Name;

        [FieldFixedLength(3)]
        [FieldTrim(TrimMode.Left)]
        [FieldNullValue(-1)]
        public int Age;

        [FieldFixedLength(13)]
        public string Tel;

        [FieldFixedLength(19)]
        [FieldConverter(ConverterKind.Date, "yyyy/MM/dd hh:mm:ss")]
        public DateTime Birthday;

        public override int GetHashCode() {
            return this.ToString().GetHashCode();
        }

        public override bool Equals(object obj) {
            if (base.Equals(obj)) {
                return true;
            }

            return (this.ToString() == ((Person)obj).ToString());
        }
        public override string ToString() {
            return string.Format("Id={0},Name={1},Age={2},Tel={3},BirthDay={4}", Id, Name, Age, Tel, Birthday);
        }
    }
}


次はデータテーブルへのマッピングにトライしてみます。



================================
過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。