예제 #1
0
        public List <Dictionary <string, object> > ReadDBFFile(Stream stream)
        {
            BinaryReader read = new BinaryReader(stream);

            //Read the DBF header info
            //The header is 32 bytes in length

            // Is it a type of file that I can handle?
            //File type:
            //    0x02   FoxBASE
            //    0x03   FoxBASE+/Dbase III plus, no memo
            //    0x30   Visual FoxPro
            //    0x31   Visual FoxPro, autoincrement enabled
            //    0x32   Visual FoxPro with field type Varchar or Varbinary
            //    0x43   dBASE IV SQL table files, no memo
            //    0x63   dBASE IV SQL system files, no memo
            //    0x83   FoxBASE+/dBASE III PLUS, with memo
            //    0x8B   dBASE IV with memo
            //    0xCB   dBASE IV SQL table files, with memo
            //    0xF5   FoxPro 2.x (or earlier) with memo
            //    0xE5   HiPer-Six format with SMT memo file
            //    0xFB   FoxBASE
            byte fileType = read.ReadByte();

            if (new byte[] { 0x02, 0x03, 0x30, 0x43, 0x63, 0x83, 0x8b,
                             0xcb, 0xf5, 0xfb }.Contains(fileType))
            {
                // Skip date.
                read.BaseStream.Seek(3, SeekOrigin.Current);

                // Read useful datas...
                uint   RecordCount            = read.ReadUInt32();
                ushort FirstRecord            = read.ReadUInt16(); //or length of header
                ushort RecordLength           = read.ReadUInt16(); //length of each record
                ushort reserved               = read.ReadUInt16();
                byte   incompleteTransaction  = read.ReadByte();
                byte   encryptionFlag         = read.ReadByte();
                uint   freeRecordThread       = read.ReadUInt32();
                byte[] reservedForMultiUserDB = read.ReadBytes(8);
                byte   tableFlags             = read.ReadByte();//0x01   file has a structural .cdx, 0x02   file has a Memo field, 0x04   file is a database (.dbc)
                byte   languageDriver         = read.ReadByte();
                ushort reserved2              = read.ReadUInt16();

                //Read all the dbf fields info
                List <DBFField> DBFFields = new List <DBFField>();
                while (read.PeekChar() != 0x0D)
                {
                    //The Field info is 32 bytes in length
                    DBFField field = new DBFField();
                    field.FieldName = Encoding.UTF8.GetString(read.ReadBytes(11), 0, 11).Replace("\0", "").ToLowerInvariant();
                    field.FieldType = read.ReadByte();
                    //Field type:
                    //    C   –   Character
                    //    Y   –   Currency
                    //    N   –   Numeric
                    //    F   –   Float
                    //    D   –   Date
                    //    T   –   DateTime
                    //    B   –   Double
                    //    I   –   Integer
                    //    L   –   Logical
                    //    M   – Memo
                    //    G   – General
                    //    C   –   Character (binary)
                    //    M   –   Memo (binary)
                    //    P   –   Picture

                    field.FieldDataAddress      = read.ReadUInt32();//Displacement of field in record
                    field.FieldLengthInBytes    = read.ReadByte();
                    field.NumberOfDecimalPlaces = read.ReadByte();
                    field.FieldFlags            = read.ReadByte();
                    //0x01   System Column (not visible to user),
                    //0x02   Column can store null values,
                    //0x04   Binary column (for CHAR and MEMO only),
                    //0x06   (0x02+0x04) When a field is NULL and binary (Integer, Currency, and Character/Memo fields),
                    //0x0C   Column is autoincrementing

                    field.NextAutoIncrementValue = read.ReadUInt32();
                    field.AutoIncrementStepValue = read.ReadByte();
                    field.ReservedBytes          = read.ReadBytes(8);

                    DBFFields.Add(field);
                }
                byte headerTerminator = read.ReadByte();//Read the header record terminator

                //Read all the records now
                read.BaseStream.Seek(FirstRecord, SeekOrigin.Begin);
                List <Dictionary <string, object> > table = new List <Dictionary <string, object> >();
                while (read.PeekChar() != 0x1A)
                {
                    byte[] recordContent            = read.ReadBytes(RecordLength);
                    Dictionary <string, object> row = new Dictionary <string, object>();
                    int currentIndex = 1;
                    foreach (DBFField field in DBFFields)
                    {
                        string temp = Encoding.UTF8.GetString(recordContent, currentIndex, field.FieldLengthInBytes);
                        temp         = temp.Trim();
                        currentIndex = currentIndex + field.FieldLengthInBytes;
                        row.Add(field.FieldName, temp);
                    }

                    table.Add(row);
                }

                return(table);
            }
            else
            {
                throw new NotSupportedException("The DBF file type is not supported.");
            }
        }
예제 #2
0
        public void ReadAttributes( Stream stream )
        {
            BinaryReader read = new BinaryReader( stream );

            //Read the DBF header info
            //The header is 32 bytes in length

            // Is it a type of file that I can handle?
            //File type:
            //    0x02   FoxBASE
            //    0x03   FoxBASE+/Dbase III plus, no memo
            //    0x30   Visual FoxPro
            //    0x31   Visual FoxPro, autoincrement enabled
            //    0x32   Visual FoxPro with field type Varchar or Varbinary
            //    0x43   dBASE IV SQL table files, no memo
            //    0x63   dBASE IV SQL system files, no memo
            //    0x83   FoxBASE+/dBASE III PLUS, with memo
            //    0x8B   dBASE IV with memo
            //    0xCB   dBASE IV SQL table files, with memo
            //    0xF5   FoxPro 2.x (or earlier) with memo
            //    0xE5   HiPer-Six format with SMT memo file
            //    0xFB   FoxBASE
            byte fileType = read.ReadByte();
            if( new byte[] { 0x02, 0x03, 0x30, 0x43, 0x63, 0x83, 0x8b,
                             0xcb, 0xf5, 0xfb }.Contains( fileType ) )
            {
                // Skip date.
                read.BaseStream.Seek( 3, SeekOrigin.Current );

                // Read useful datas...
                uint RecordCount = read.ReadUInt32();
                ushort FirstRecord = read.ReadUInt16();//or length of header
                ushort RecordLength = read.ReadUInt16();//length of each record
                ushort reserved = read.ReadUInt16();
                byte incompleteTransaction = read.ReadByte();
                byte encryptionFlag = read.ReadByte();
                uint freeRecordThread = read.ReadUInt32();
                byte[] reservedForMultiUserDB = read.ReadBytes( 8 );
                byte tableFlags = read.ReadByte();//0x01   file has a structural .cdx, 0x02   file has a Memo field, 0x04   file is a database (.dbc)
                byte languageDriver = read.ReadByte();
                ushort reserved2 = read.ReadUInt16();

                if( RecordCount != records.Count )
                    throw new InvalidOperationException( "The number of records in the DBF files does not match the number of records in the SHP file." );

                //Read all the dbf fields info
                List<DBFField> DBFFields = new List<DBFField>();
                while( read.PeekChar() != 0x0D )
                {
                    //The Field info is 32 bytes in length
                    DBFField field = new DBFField();
                    field.FieldName = Encoding.UTF8.GetString( read.ReadBytes( 11 ), 0, 11 ).Replace( "\0", "" ).ToLower();
                    field.FieldType = read.ReadByte();
                    //Field type:
                    //    C   –   Character
                    //    Y   –   Currency
                    //    N   –   Numeric
                    //    F   –   Float
                    //    D   –   Date
                    //    T   –   DateTime
                    //    B   –   Double
                    //    I   –   Integer
                    //    L   –   Logical
                    //    M   – Memo
                    //    G   – General
                    //    C   –   Character (binary)
                    //    M   –   Memo (binary)
                    //    P   –   Picture

                    field.FieldDataAddress = read.ReadUInt32();//Displacement of field in record
                    field.FieldLengthInBytes = read.ReadByte();
                    field.NumberOfDecimalPlaces = read.ReadByte();
                    field.FieldFlags = read.ReadByte();
                    //0x01   System Column (not visible to user),
                    //0x02   Column can store null values,
                    //0x04   Binary column (for CHAR and MEMO only),
                    //0x06   (0x02+0x04) When a field is NULL and binary (Integer, Currency, and Character/Memo fields),
                    //0x0C   Column is autoincrementing

                    field.NextAutoIncrementValue = read.ReadUInt32();
                    field.AutoIncrementStepValue = read.ReadByte();
                    field.ReservedBytes = read.ReadBytes( 8 );

                    DBFFields.Add( field );
                }
                byte headerTerminator = read.ReadByte();//Read the header record terminator

                //Read all the records now
                read.BaseStream.Seek( FirstRecord, SeekOrigin.Begin );
                int recordIndex = 0;
                while(read.PeekChar() != 0x1A)
                {
                    byte[] recordContent = read.ReadBytes( RecordLength );
                    Dictionary<string, object> row = new Dictionary<string, object>();
                    int currentIndex = 1;
                    foreach( DBFField field in DBFFields )
                    {
                        string temp = Encoding.UTF8.GetString( recordContent, currentIndex, field.FieldLengthInBytes );
                        currentIndex = currentIndex + field.FieldLengthInBytes;
                        row.Add( field.FieldName, temp );
                    }

                    this.records[ recordIndex ].Attributes = row;
                    recordIndex++;
                }
            }
            else
            {
                return;
            }
        }