Beispiel #1
0
 public DbaseWriter(string filename)
 {
     _dbaseFileStream = File.Open(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
     _dbaseWriter     = new BinaryWriter(_dbaseFileStream, Encoding.ASCII);
     _dbaseReader     = new BinaryReader(_dbaseFileStream);
     if (_dbaseFileStream.Length > 0)
     {
         _header = DbaseHeader.ParseDbfHeader(_dbaseReader);
         _schema = DbaseSchema.GetFeatureTableForFields(_header.Columns);
     }
 }
Beispiel #2
0
        internal static DbaseHeader ParseDbfHeader(BinaryReader reader)
        {
            DbaseHeader header = new DbaseHeader();

            if (reader.ReadByte() != DbaseConstants.DbfVersionCode)
            {
                throw new NotSupportedException("Unsupported DBF Type");
            }

            header.LastUpdate  = new DateTime((int)reader.ReadByte() + 1900, (int)reader.ReadByte(), (int)reader.ReadByte());             //Read the last update date
            header.RecordCount = reader.ReadUInt32();                                                                                     // read number of records.
            short storedHeaderLength = reader.ReadInt16();                                                                                // read length of header structure.
            short storedRecordLength = reader.ReadInt16();                                                                                // read length of a record

            reader.BaseStream.Seek(DbaseConstants.EncodingOffset, SeekOrigin.Begin);                                                      //Seek to encoding flag
            header.LanguageDriver = reader.ReadByte();                                                                                    //Read and parse Language driver
            reader.BaseStream.Seek(DbaseConstants.ColumnDescriptionOffset, SeekOrigin.Begin);                                             //Move past the reserved bytes

            int numberOfColumns = (storedHeaderLength - DbaseConstants.ColumnDescriptionOffset) / DbaseConstants.ColumnDescriptionLength; // calculate the number of DataColumns in the header

            DbaseField[] columns = new DbaseField[numberOfColumns];
            for (int i = 0; i < columns.Length; i++)
            {
                columns[i]            = new DbaseField();
                columns[i].ColumnName = System.Text.Encoding.UTF7.GetString((reader.ReadBytes(11))).Replace("\0", "").Trim();
                char fieldtype = reader.ReadChar();

                columns[i].Address = reader.ReadInt32();

                short fieldLength = reader.ReadByte();
                if (fieldtype == 'N' || fieldtype == 'F')
                {
                    columns[i].Decimals = reader.ReadByte();
                }
                else
                {
                    fieldLength += (short)((short)reader.ReadByte() << 8);
                }

                columns[i].Length = fieldLength;

                switch (fieldtype)
                {
                case 'L':
                    columns[i].DataType = typeof(bool);
                    break;

                case 'C':
                    columns[i].DataType = typeof(string);
                    break;

                case 'D':
                    columns[i].DataType = typeof(DateTime);
                    break;

                case 'N':
                    //If the number doesn't have any decimals, make the type an integer, if possible
                    if (columns[i].Decimals == 0)
                    {
                        if (columns[i].Length <= 4)
                        {
                            columns[i].DataType = typeof(Int16);
                        }
                        else if (columns[i].Length <= 9)
                        {
                            columns[i].DataType = typeof(Int32);
                        }
                        else if (columns[i].Length <= 18)
                        {
                            columns[i].DataType = typeof(Int64);
                        }
                        else
                        {
                            columns[i].DataType = typeof(double);
                        }
                    }
                    else
                    {
                        columns[i].DataType = typeof(double);
                    }
                    break;

                case 'F':
                    columns[i].DataType = typeof(float);
                    break;

                case 'B':
                    columns[i].DataType = typeof(byte[]);
                    break;

                default:
                    throw new NotSupportedException("Invalid or unknown DBase field type '" + fieldtype +
                                                    "' in column '" + columns[i].ColumnName + "'");
                }

                // Move stream to next field record
                reader.BaseStream.Seek(DbaseConstants.BytesFromEndOfDecimalInFieldRecord, SeekOrigin.Current);
            }

            header.Columns = columns;
            if (storedHeaderLength != header.HeaderLength)
            {
                throw new Exception("Recorded header length doesn't equal computed header length");
            }
            if (storedRecordLength != header.RecordLength)
            {
                throw new Exception("Recorded record length doesn't equal computed record length");
            }

            return(header);
        }