Code to read Memo fields

Aug 25, 2010 at 3:24 AM

Hi! Congratulations again for the excellent lib! It helped me a lot.

I also needed to read Memo fields. So I made the following changes:

- DbfHeader.cs , method Read:

      if (nFileType != 0x03 && nFileType != 0x83) // 0x83 = dbase III with memo fields

The Memo fields are stored in a file with the same name of the DBF file but with extension DBT. The field content in the DBF contains the index of a 512-byte block with the content of the Memo. The end of the Memo is found looking for the terminator 0x1a, 0x00, 0x1a, 0x00. I crafted the following draft code:

        string GetMemoField(string recordContent, string dbtFile)
        {
            if (recordContent.Trim().Length > 0)
            {
                int block = Int32.Parse(recordContent);
                return GetMemoField(block, dbtFile);
            }

            return ""; // memo has no content: maybe should be null for more correctness
        }

        string GetMemoField(int blockIndex, string dbtFile)
        {
            using (FileStream fs = new FileStream(dbtFile, FileMode.Open, FileAccess.Read))
            {
                long start = blockIndex * 512;
                StringBuilder sb = new StringBuilder();
                StreamReader sr = new StreamReader(fs);
                fs.Seek(start, SeekOrigin.Begin);
                while (fs.Position < fs.Length)
                {
                    byte c = (byte) fs.ReadByte();
                    long pos = fs.Position;
                    if (c == 0x1a && fs.ReadByte() == 0 && fs.ReadByte() == 0x1a && fs.ReadByte() == 0)
                        return sb.ToString();
                    else
                        fs.Seek(pos, SeekOrigin.Begin);
                    sb.Append((char) c);
                }
            }

            throw new InvalidOperationException();
        }

Best regards,

Cesar Mello