次は、固定長データのマッピングにトライ。
やり方はデリミタデータの場合とほぼ同じです。
つまり、マッピングクラスを適切に定義できれば勝ちです。
今回のサンプルデータは以下のようなデータです。(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); } } }
次はデータテーブルへのマッピングにトライしてみます。
================================
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場