0

従業員のデータと画像の記録を含むファイルがあります。1 人の従業員とそのデータ、彼の画像、および妻の画像の各レコード。ファイル構造を変更できない

テキストデータと画像の間にはセパレータがあります。

1 つのレコードのサンプルを次に示します

レコード番号D01=社員名!=IMG1=社員画像~\IMG2=妻画像^! \r\n

( D01= & !=IMG1= & ~\IMG2= & ^! )はセパレーターです

これは、ファイルがどのように書かれたかのコードです:

FileStream fs = new FileStream(filePath, FileMode.Create);
StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);
BinaryWriter bw = new BinaryWriter(fs);

sw.Write(employeeDataString);
sw.Write("!=IMG1=");
sw.Flush();

bw.Write(employeeImg, 0, employeeImg.Length);
bw.Flush();

sw.Write(@"~\IMG2=");
sw.Flush();

bw.Write(wifeImg, 0, wifeImg.Length);
bw.Flush();

sw.Write("^!");
sw.Flush();

sw.Write(@"\r\n");
sw.Flush();

では、そのファイルを読み取るにはどうすればよいでしょうか。

4

1 に答える 1

0

多くの種類のファイルがあります。レコードを保存する最も一般的な 3 つの方法は次のとおりです。

  • 固定サイズのレコード。固定サイズのフィールドが理想的です。ランダム アクセスの実装は非常に簡単です。
  • タグとデータが織り交ぜられたタグ付きファイル。タグはデータの位置と長さを保持するため、少し複雑ですが、柔軟性が高く、かなり効率的に読み取り可能です。
  • そして、分離されたファイルがあります。いつも痛い。

2 つの問題:

  • セパレーターがデータに含まれていないことを確認する必要があります。画像のようなバイナリ データがある場合、100% 可能ではありません。
  • 個々のレコードにアクセスする効率的な方法はありません..

最初の問題は無視して、すべてのレコードを class のリストに読み込むコードを次に示しますARecord

FileStream fs;
BinaryReader br;
List<ARecord> theRecords;

class ARecord
{
    public string name { get; set; }
    public Image img1 { get; set; }
    public Image img2 { get; set; }
}

int readFile(string filePath)
{
    fs = new FileStream(filePath, FileMode.Open);
    br = new BinaryReader(fs, Encoding.UTF8);

    theRecords = new List<ARecord>();
    ARecord record = getNextRecord();
    while (record != null)
    {
        theRecords.Add(record);
        record = getNextRecord();
    }
    return theRecords.Count;
}

ARecord getNextRecord()
{
    ARecord record = new ARecord ();

    MemoryStream ms;
    System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
    byte[] sepImg1 = enc.GetBytes(@"!=IMG1=");
    byte[] sepImg2 = enc.GetBytes(@"~\IMG2=");
    byte[] sepRec = enc.GetBytes(@"^!\r\n");

    record.name = enc.GetString(readToSep(sepImg1));

    ms = new MemoryStream(readToSep(sepImg2));
    if (ms.Length <= 0) return null;             // check for EOF
    record.img1 = Image.FromStream(ms);

    ms = new MemoryStream(readToSep(sepRec));
    record.img2 = Image.FromStream(ms);

    return record;
}

byte[] readToSep(byte[] sep)
{
    List<byte> data = new List<byte>();
    bool eor = false;
    int sLen = sep.Length;
    int sPos = 0;
    while (br.BaseStream.Position < br.BaseStream.Length && !eor )
    {
        byte b = br.ReadByte();
        data.Add(b);
        if (b != sep[sPos]) { sPos = 0; }
        else if (sPos < sLen - 1) sPos++; else eor = true;
    }
    if (data.Count > sLen ) data.RemoveRange(data.Count - sLen , sLen );
    return data.ToArray();
}

ノート:

  • エラーチェックは一切ありません。
  • それらのセパレーターに注意してください!本当に正しいです@か??
  • コードを展開してレコード番号を作成するのはあなた次第です
于 2014-09-24T06:43:01.237 に答える