从分离的文件中读取二进制数据(图像)

时间:2014-09-23 13:57:32

标签: c# encoding binaryreader binarywriter

我有一个文件,其中包含员工数据和图像的记录。每个员工的记录和他的数据,他的形象和他的妻子形象。 我无法更改文件结构

文本数据和图像之间存在分隔符。

此处是一条记录的示例

记录编号 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();

那么如何阅读该文件?

1 个答案:

答案 0 :(得分:0)

有多种文件;存储记录的三种最常用方法是

  • 固定大小记录,理想情况下使用固定大小的字段。实现随机访问非常简单。
  • 带有标签和数据交织在一起的标记文件。由于标签保存数据的位置和长度,因此有点复杂但高度灵活并且仍然具有相当高的可读性。
  • 然后有分隔文件。总是很痛苦。

两个问题:

  • 您必须确保分隔符永远不在数据中。当您拥有像图像这样的二进制数据时,这不是100%可能。
  • 没有有效的方式来访问个别记录..

忽略第一个问题,这是一段代码,它将所有记录读入类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();
}

注意:

  • 没有任何错误检查。
  • 观看那些分隔符!是@真的对吗??
  • 扩展代码以创建记录号留给你