예제 #1
0
        /// <summary>
        /// Read a single row from the dBase file
        /// </summary>
        /// <param name="header">DBase File header</param>
        /// <param name="reader">BinaryReader that stream is being read from</param>
        /// <param name="colRules">List of column indices to skip</param>
        /// <param name="numValidRulesCols">Number of columns that are marked true in the column rules array</param>
        /// <returns>A Dictionary of objects</returns>
        internal static Dictionary <string, object> ReadRow(DBaseFileHeader header, BinaryReader reader, bool[] colRules, int numValidRulesCols)
        {
            Dictionary <string, object> row = null;

            bool foundRow = false;

            //loop through until there are no more valid rows
            while (!foundRow)
            {
                //Initialize DBaseRow
                row = new Dictionary <string, object>();

                //Read the deleted flag
                char deletedFlag = (char)reader.ReadChar();

                //Read the row length
                int rowLength = 1; // for the deleted character just read.

                char[] buffer;     //a reusable character array used for holding characters
                string tempString; //a resuable variable for string a string
                object cellObject;

                //Read the rows
                for (int j = 0; j < header.NumColumns; j++)
                {
                    //Get the cell length
                    int cellLength = header.ColumnDescriptions[j].Length;
                    rowLength = rowLength + cellLength;

                    // read the data.
                    cellObject = null;

                    if (colRules == null || colRules[j])
                    {
                        //Switch on the DBaseType of the cell
                        switch (header.ColumnDescriptions[j].DBaseType)
                        {
                        case 'L':       //boolean
                            char tempChar = (char)reader.ReadByte();

                            // Check DBase boolean characters (T,t,F,f,Y,y,N,n)
                            if (char.ToUpper(tempChar) == 'T' || char.ToUpper(tempChar) == 'Y')
                            {
                                cellObject = true;
                            }
                            else
                            {
                                cellObject = false;
                            }
                            break;

                        case 'C':       //String or character
                            buffer = new char[cellLength];
                            buffer = reader.ReadChars(cellLength);

                            //Trim whitespaces and remove any \0 values
                            cellObject = new string(buffer).Trim().Replace("\0", String.Empty);
                            break;

                        case 'D':       //Date YYYYMMDD
                            buffer = new char[8];
                            buffer = reader.ReadChars(8);

                            //Parse the date parameters out of the character array
                            int year  = Int32.Parse(new string(buffer, 0, 4), CultureInfo.InvariantCulture);
                            int month = Int32.Parse(new string(buffer, 4, 2), CultureInfo.InvariantCulture);
                            int day   = Int32.Parse(new string(buffer, 6, 2), CultureInfo.InvariantCulture);

                            //create a DateTime object
                            cellObject = new DateTime(year, month, day);
                            break;

                        case 'I':       //Integer
                            buffer     = new char[cellLength];
                            buffer     = reader.ReadChars(cellLength);
                            tempString = new string(buffer).Trim();

                            int intNumber;

                            //Try and parse the integer
                            if (int.TryParse(tempString, NumberStyles.Integer, CultureInfo.InvariantCulture, out intNumber))
                            {
                                cellObject = intNumber;
                            }
                            break;

                        case 'N':     //Double
                            buffer     = new char[cellLength];
                            buffer     = reader.ReadChars(cellLength);
                            tempString = new string(buffer).Trim();

                            double doubleNumber;

                            //Try and parse the double
                            if (double.TryParse(tempString, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out doubleNumber))
                            {
                                cellObject = doubleNumber;
                            }
                            break;

                        case 'F':     //float
                            buffer     = new char[cellLength];
                            buffer     = reader.ReadChars(cellLength);
                            tempString = new string(buffer).Trim();

                            float floatNumber;

                            //Try and parse the float
                            if (float.TryParse(tempString, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out floatNumber))
                            {
                                cellObject = floatNumber;
                            }
                            break;

                        default:
                            break;
                        }

                        //Add the cell object to the row
                        row.Add(header.ColumnDescriptions[j].Name, cellObject);
                    }
                    else
                    {
                        reader.BaseStream.Seek(cellLength, SeekOrigin.Current);
                    }
                }

                //Check to see if the full row has been read.
                if (rowLength < header.RowLength)
                {
                    //Skip to the end of the row
                    reader.BaseStream.Seek(header.RowLength - rowLength, SeekOrigin.Current);
                }

                //Add the row if it is not deleted.
                if (deletedFlag != '*')
                {
                    foundRow = true;
                }
            }

            return(row);
        }
예제 #2
0
        /// <summary>
        /// Reads the header data from a DBF file using a BinarayReader
        /// </summary>
        /// <param name="reader">BinaryReader containing the DBF file</param>
        /// <returns>A DBaseFileHeader object with the header information of the DBF file</returns>
        public static DBaseFileHeader ReadHeader(BinaryReader reader)
        {
            //initialize the dBase Header object
            DBaseFileHeader header = new DBaseFileHeader();

            //The first byte in the reader should be the file type. Verify that this is correct.
            if (reader.ReadByte() == requiredFileType)
            {
                //Read the date parameters
                int year  = (int)reader.ReadByte() + 1900;
                int month = (int)reader.ReadByte();
                int day   = (int)reader.ReadByte();
                header.LastUpdateDate = new DateTime(year, month, day);

                //Read the number of records.
                header.NumRows = reader.ReadInt32();

                //Read the length of the header structure.
                header.HeaderLength = reader.ReadInt16();

                //Read the length of a record
                header.RowLength = reader.ReadInt16();

                //Skip the reserved bytes in the header.
                reader.BaseStream.Seek(20, SeekOrigin.Current);

                //Calculate the number of columns in the header
                header.NumColumns = (header.HeaderLength - fileDescriptionSize - 1) / fileDescriptionSize;

                //Inialize the ColumDescriptions List
                header.ColumnDescriptions = new List <DBaseColumnDefinition>(header.NumColumns);

                for (int i = 0; i < header.NumColumns; i++)
                {
                    DBaseColumnDefinition columnDescription = new DBaseColumnDefinition();

                    //Read the cloumn name
                    char[] buffer = new char[11];
                    buffer = reader.ReadChars(11);
                    columnDescription.Name = new string(buffer).Replace("\0", String.Empty);

                    //Read the column dBase data type
                    columnDescription.DBaseType = (char)reader.ReadByte();

                    //Skip the column data address
                    reader.ReadInt32();

                    //Read the column length in bytes
                    int columnLength = (int)reader.ReadByte();

                    //Make sure the length is positive
                    if (columnLength < 0)
                    {
                        columnLength += 256;
                    }

                    columnDescription.Length = columnLength;

                    //Skip the column decimal count property and the reserved bytes.
                    reader.BaseStream.Seek(15, SeekOrigin.Current);

                    //Add the column description to the list of descriptions
                    header.ColumnDescriptions.Add(columnDescription);
                }

                //The last byte is a marker for the end of the field definitions.
                reader.BaseStream.Seek(1, SeekOrigin.Current);
            }

            return(header);
        }