固定長レコードに対する操作って、ハンディターミナルでは以外と需要があったり

本日のお仕事はこんなカンジ。
Compact Frameworkで使用するための、固定長レコードのファイルに対する操作を行うクラスを、下記の様なインタフェースで用意してみましたがどうでしょう(´д`)

// 固定長レコードの操作クラス
public class FixedRecordFile : IDisposable
{
    public string FileName { get; }
    public int RecordSize { get; }
    public bool IsOpen { get; }
    public long FileLength { get; }
    public int RecordCount { get; }

    public FixedRecordFile(string filename, int recordSize);
    public FixedRecordFile(string filename, int recordSize, bool keepStream){}
    public void Dispose();

    public void Open();
    public void Close() ;

    // indexの1件取得
    public byte[] GetRecordBytes(int index);

    // finderにマッチする1件取得
    public byte[] Select(Func<byte[], int> finder);
    // finderにマッチする1件の位置取得
    public int SelectIndex(Func<byte[], int> finder);

    // finderにマッチする複数件取得
    public List<byte[]> SelectMulti(Func<byte[], int> finder);
    // finderにマッチする複数件の位置取得
    public List<int> SelectIndexMulti(Func<byte[], int> finder);

    // conditionを使った全件検索
    public List<byte[]> SelectIf(Predicate<byte[]> condition);

    // 最終レコードに追加
    public void Add(byte[] data);

    // indexの位置に挿入
    public void Insert(int index, byte[] data);
    // finderで見つけた位置に挿入
    public void Insert(Func<byte[], int> finder, byte[] data);

    // indexの位置を更新
    public void Update(int index, byte[] data);
    // finderで見つけた位置を更新
    public void Update(Func<byte[], int> finder, byte[] data);

    // finderで見つけた複数件を更新
    public void UpdateMulti(Func<byte[], int> finder, Func<byte[], byte[]> updater);

    // conditionを使った全件検索でupdaterによる更新
    public void UpdateIf(Predicate<byte[]> condition, Func<byte[], byte[]> updater);

    // indexの位置を削除
    public void Delete(int index);
    // finderで見つけた位置を削除
    public void Delete(Func<byte[], int> finder);

    // finderで見つけた複数件の位置を削除
    public void DeleteMutli(Func<byte[], int> finder);

    // conditionを使った全件検索による削除
    public void DeleteIf(Predicate<byte[]> condition);

    // 全件削除SetLength(0)
    public void DeleteAll();

    // sorterによるソート
    public void Sort(Func<byte[], byte[], int> sorter);
}
// FixedRecordFileのByteMarshaler用版
public class FixedRecordFile<T> : FixedRecordFile where T : ByteMarshaler
{
    public FixedRecordFile(string filename);
    public FixedRecordFile(string filename, bool keepStream);

    public T GetRecord(int index);

    public T Select(Func<T, int> finder);
    public int SelectIndex(Func<T, int> finder);

    public List<T> SelectMulti(Func<T, int> finder);
    public List<int> SelectIndexMulti(Func<T, int> finder);

    public List<T> SelectIf(Predicate<T> condition);

    public void Add(T data);

    public void Insert(int index, T data);
    public void Insert(Func<T, int> finder, T data);

    public void Update(int index, T data);
    public void Update(Func<T, int> finder, T data);

    public void UpdateMulti(Func<T, int> finder, Func<T, T> updater);

    public void UpdateIf(Predicate<T> condition, Func<T, T> updater);

    public void Delete(Func<T, int> finder);

    public void DeleteMutli(Func<T, int> finder);

    public void DeleteIf(Predicate<T> condition);

    public void Sort(Func<T, T, int> sorter);
}

なぜDBではなく固定長ファイルかと言えば、上位(基幹)のシステムから降ってきたファイルをそのまま使ったりすることもあるため。
ByteMarshalerはStructLayoutAttribute.Packに対する対応策(´・ω・`)


使い方としては、下記の様なデータ構造に対して、

4900000000001,9999,A,20080101
4900000000002,    ,A,20080101
4900000000003,   0,A,20080101
4900000000004, 123,A,20080101
4900000000004, 123,B,20080101

こんなカンジのレコードクラスを用意。

[RecordMarshalAttribute( Size = 31, Blank = (byte)',' )]
public class Record : ByteMarshaler
{
    [FieldMarshal( Offset = 0, Size = 13 )]
    [SjisFieldConverter]
    public string Jancode { get; set; }

    [FieldMarshal( Offset = 14, Size = 4 )]
    [SjisFieldConverter( PadLeft = true, EmptyToNull = true )]
    public Nullable<int> Qty { get; set; }

    [FieldMarshal( Offset = 19 )]
    public byte Type { get; set; }

    [FieldMarshal( Offset = 21, Size = 8 )]
    [DateStringConverter]
    public DateTime Date { get; set; }

    [FieldMarshal( Offset = 29, Length = 2 )]
    protected byte[] CRLF = new byte[] { 0x0d, 0x0a };
}

っで、検索をしたい時はこんなカンジで(・∀・)

FixedRecordFile<Record> file = new FixedRecordFile<Record>( filename );

Record record = file.Select( x => x.Jancode.CompareTo( "4900000000003" ) );

そして明日からはNet周りの再整理(・ω・)