Чтение DBF - формата

Нашел в Интернете отличный пример чтение DBF — формата в DataTable. Решил его опубликовать, может кому пригодится. Отлично работает в Compact Framework.


private void ReadDBF(string filename)
        {
            //читаем DBF - файл
            FileStream fs = null;

            try
            {
                dt = new DataTable();
                fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
                byte[] buffer = new byte[4]; // Кол-во записей: 4 байтa, начиная с 5-го
                fs.Position = 4;
                fs.Read(buffer, 0, buffer.Length);
                int RowsCount = buffer[0] + (buffer[1] * 0x100) + (buffer[2] * 0x10000) + (buffer[3] * 0x1000000);
                buffer = new byte[2]; // Кол-во полей: 2 байтa, начиная с 9-го
                fs.Position = 8;
                fs.Read(buffer, 0, buffer.Length);
                int FieldCount = (((buffer[0] + (buffer[1] * 0x100)) - 1) / 32) - 1;
                string[] FieldName = new string[FieldCount]; // Массив названий полей
                string[] FieldType = new string[FieldCount]; // Массив типов полей
                byte[] FieldSize = new byte[FieldCount]; // Массив размеров полей
                byte[] FieldDigs = new byte[FieldCount]; // Массив размеров дробной части
                buffer = new byte[32 * FieldCount]; // Описание полей: 32 байтa * кол-во, начиная с 33-го
                fs.Position = 32;
                fs.Read(buffer, 0, buffer.Length);
                int FieldsLength = 0;
                for (int i = 0; i < FieldCount; i++)
                {
                    // Заголовки
                    FieldName[i] = System.Text.Encoding.Default.GetString(buffer, i * 32, 10).TrimEnd(new char[] { (char)0x00 });
                    FieldType[i] = "" + (char)buffer[i * 32 + 11];
                    FieldSize[i] = buffer[i * 32 + 16];
                    FieldDigs[i] = buffer[i * 32 + 17];
                    FieldsLength = FieldsLength + FieldSize[i];
                    // Создаю колонки
                    switch (FieldType[i])
                    {
                        case "L": dt.Columns.Add(FieldName[i], Type.GetType("System.Boolean")); break;
                        case "D": dt.Columns.Add(FieldName[i], Type.GetType("System.DateTime")); break;
                        case "N":
                            {
                                if (FieldDigs[i] == 0)
                                    dt.Columns.Add(FieldName[i], Type.GetType("System.Int32"));
                                else
                                    dt.Columns.Add(FieldName[i], Type.GetType("System.Decimal"));
                                break;
                            }
                        case "F": dt.Columns.Add(FieldName[i], Type.GetType("System.Double")); break;
                        default: dt.Columns.Add(FieldName[i], Type.GetType("System.String")); break;
                    }
                }
                fs.ReadByte(); // Пропускаю разделитель схемы и данных
                System.Globalization.DateTimeFormatInfo dfi = new System.Globalization.CultureInfo("en-US", false).DateTimeFormat;
                System.Globalization.NumberFormatInfo nfi = new System.Globalization.CultureInfo("en-US", false).NumberFormat;
                buffer = new byte[FieldsLength];
                dt.BeginLoadData();
                for (int j = 0; j < RowsCount; j++)
                {
                    fs.ReadByte(); // Пропускаю стартовый байт элемента данных
                    fs.Read(buffer, 0, buffer.Length);
                    System.Data.DataRow R = dt.NewRow();
                    int Index = 0;
                    for (int i = 0; i < FieldCount; i++)
                    {
                        string l = System.Text.Encoding.GetEncoding(Encoding.UTF8.HeaderName).GetString(buffer, Index, FieldSize[i]).TrimEnd(new char[] { (char)0x00 }).TrimEnd(new char[] { (char)0x20 });
                        Index = Index + FieldSize[i];
                        if (l != "")
                            switch (FieldType[i])
                            {
                                case "L": R[i] = l == "T" ? true : false; break;
                                case "D": R[i] = DateTime.ParseExact(l, "yyyyMMdd", dfi); break;
                                case "N":
                                    {
                                        if (FieldDigs[i] == 0)
                                            R[i] = int.Parse(l, nfi);
                                        else
                                            R[i] = decimal.Parse(l, nfi);
                                        break;
                                    }
                                case "F": R[i] = double.Parse(l, nfi); break;
                                default: R[i] = l; break;
                            }
                        else
                            R[i] = DBNull.Value;
                    }
                    dt.Rows.Add®;
                    Application.DoEvents();
                }
                dt.EndLoadData();
                fs.Close();
            }
            catch (Exception e)
            {
                //
            }
            finally
            {
                if (fs != null)
                {
                    fs.Dispose();
                }
            }       
        }


Спасибо автору.

работа с OSM картами (QGIS) в среде Compact Framework

Разрабатывая очередное приложение, наткнулся на проблему связанную с открытием карт созданных в системе QGIS на мобильном устройстве с системой Windows Mobile. Проблему решил в течении 2-х недель. Кому это интересно пишете, с радостью отвечу. Почему не пишу сразу? Тема очень обширная, будет вопрос будет ответ. Классы разработанные мной можно переписать и для Phone 7 и для Android.