public static DataTable LoadSchema(DbfHeader dbf)
        {
            DataTable dtRet = new DataTable();

            // Add the DBF fields to the DataTable
            foreach (DbfField fld in dbf.Fields)
            {
                DataColumn dc = new DataColumn(fld.FieldName.Trim());
                switch (fld.FieldDataType)
                {
                case DbfHeader.dBaseFieldType.Character:
                    dc.DataType  = typeof(System.String);
                    dc.MaxLength = fld.FieldLength;
                    break;

                case DbfHeader.dBaseFieldType.Date:
                    dc.DataType = typeof(System.DateTime);
                    break;

                case DbfHeader.dBaseFieldType.Logical:
                    dc.DataType = typeof(System.Boolean);
                    break;

                case DbfHeader.dBaseFieldType.Memo:
                    dc.DataType = typeof(System.Int32);
                    break;

                case DbfHeader.dBaseFieldType.Numeric:
                    dc.DataType = typeof(System.String);
                    break;
                }
                dtRet.Columns.Add(dc);
            }
            return(dtRet);
        }
 public DbfField(string fldName, DbfHeader.dBaseFieldType fldType, int recOffset, int fldLength, int decLength, int ordinal)
 {
     this.FieldNameHex = Hex.ToHex(Encoding.Unicode.GetBytes(fldName));
     this.FieldTypeHex = Hex.ToHex(new byte[] { (byte)fldType });
     this.RecordOffsetHex = Hex.ToHex(recOffset).PadLeft(8, '0');
     this.FieldLength = fldLength;
     this.DecimalLength = decLength;
     this.Ordinal = ordinal;
     this.Owner = null;
 }
        public static DbfTable WriteDbf(DataTable dt, FileStream fs, DbfHeader dbStruct)
        {
            // This string contains all the system data types that map to a
            //   particular DBF data type.  This saves from crazy-long
            //   "if" statements.
            string numericType = "Int16,Int32,Int64,Float,Double,Decimal";

            // This DbfField collection stores the info about the fields
            //   in the DBF file we're creating.
            DbfFieldCollection flds = new DbfFieldCollection();

            #region Write DBF Header
            // The first byte is the version identifier.
            // Here, we're specifying dBase IV.
            fs.WriteByte((byte)DbfHeader.dBaseType.dBase4WithOutMemo);
            // The next three bytes are the date that the file
            //   was last modified.
            DateTime dtNow = DateTime.Now;
            fs.Write(new byte[] { (byte)(dtNow.Year - 1900), (byte)dtNow.Month, (byte)dtNow.Day }, 0, 3);
            // The next four bytes contain a count of the number of records
            //   in the file.  NOTE:  these values are stored in reverse order.
            byte[] recCnt = Hex.GetBytes(Hex.ToHex(dt.Rows.Count).PadLeft(8, '0'));
            Array.Reverse(recCnt);
            fs.Write(recCnt, 0, 4);
            // The next two bytes indicate the offset to the start of the
            //   actual data. NOTE: these values are stored in reverse  order.
            // The base header takes 32 bytes and each field header takes an
            //   additional 32 bytes.
            byte[] hdrSize = Hex.GetBytes(Hex.ToHex(32 + (dt.Columns.Count * 32)).PadLeft(4, '0'));
            Array.Reverse(hdrSize);
            fs.Write(hdrSize, 0, 2);
            // The next two bytes identify the size of each record. This number
            //   represents the sum of all field lengths + 1, due to the first
            //   byte of each record being a deletion flag. NOTE: these values
            //   are stored in reverse order.
            int recLen = 0;
            foreach (DataColumn dc in dt.Columns)
            {
                recLen += (dc.MaxLength > 0) ? dc.MaxLength : 100;
            }
            byte[] recSize = Hex.GetBytes(Hex.ToHex(recLen + 1).PadLeft(4, '0'));
            Array.Reverse(recSize);
            fs.Write(recSize, 0, 2);
            // The next sixteen bytes are not used, so we just fill the
            //   space with zeros.
            byte[] nullBytes = new byte[16]; nullBytes.Initialize();
            fs.Write(nullBytes, 0, 16);
            // The next byte is the compound index flag. This flag should be set to
            //   0x01h if a stuctural CDX file is attached to the database.
            // At present, I don't know how to write or read these, so I will
            //   hardcode this to 0x00h.
            fs.WriteByte(0x00);
            // The next three bytes are also not used, so fill with zeros.
            nullBytes = new byte[3]; nullBytes.Initialize();
            fs.Write(nullBytes, 0, 3);
            #endregion

            #region Write Field Headers
            // Now we parse and write the header for each column.
            int fldOffset = 0;
            if (dbStruct != null)
            {
                flds = dbStruct.Fields;
                byte[] fldsHdr = dbStruct.Fields.GetRawHeader();
                fs.Write(fldsHdr, 0, fldsHdr.Length);
            }
            else
            {
                foreach (DataColumn dc in dt.Columns)
                {
                    DbfHeader.dBaseFieldType fldType;
                    if (dc.DataType.Name == "DateTime")
                    {
                        fldType = DbfHeader.dBaseFieldType.Date;
                    }
                    else if (numericType.Contains(dc.DataType.Name))
                    {
                        fldType = DbfHeader.dBaseFieldType.Numeric;
                    }
                    else if (dc.DataType.Name == "Boolean")
                    {
                        fldType = DbfHeader.dBaseFieldType.Logical;
                    }
                    else
                    {
                        fldType = DbfHeader.dBaseFieldType.Character;
                    }

                    string fldName = dc.ColumnName.Substring(0, (dc.ColumnName.Length <= 10) ? dc.ColumnName.Length : 10);
                    //int fldSize = (dc.MaxLength > 0 || dc.DataType.Name != "String") ? dc.MaxLength : 100;
                    int fldSize = 50;
                    if (dc.DataType.Name == "DateTime")
                    {
                        fldSize = 8;
                    }
                    else if (dc.MaxLength > 0)
                    {
                        fldSize = dc.MaxLength;
                    }

                    flds.Add(new DbfField(fldName, fldType, fldOffset, fldSize, 0, dc.Ordinal));
                    fldOffset += fldSize;
                }
                byte[] fldsHdr = flds.GetRawHeader();
                fs.Write(fldsHdr, 0, fldsHdr.Length);
            }
            #endregion

            #region Write DBF Data
            foreach (DataRow dr in dt.Rows)
            {
                // The first byte of every record is the deletion flag.
                fs.WriteByte(0x00);
                // Convert each value to a byte array & add it to the buffer.
                for (int i = 0; i < dbStruct.Fields.Count; i++)
                {
                    byte[] record = new byte[0];
                    if (flds[i].FieldDataType == DbfHeader.dBaseFieldType.Date)
                    {
                        try
                        { record = Array.ConvertAll <Char, Byte>(((DateTime)dr[i]).ToString("yyyyMMdd").ToCharArray(), new Converter <Char, Byte>(Convert.ToByte)); }
                        catch (InvalidCastException)
                        { record = Array.ConvertAll <Char, Byte>("        ".ToCharArray(), new Converter <Char, Byte>(Convert.ToByte)); }
                    }
                    else if (flds[i].FieldDataType == DbfHeader.dBaseFieldType.Memo)
                    {
                        record = Array.ConvertAll <Char, Byte>("00000000".ToCharArray(), new Converter <char, byte>(Convert.ToByte));
                    }
                    else
                    {
                        record = Array.ConvertAll <Char, Byte>(dr[i].ToString().PadRight(flds[i].FieldLength, ' ').ToCharArray(), new Converter <Char, Byte>(Convert.ToByte));
                    }
                    fs.Write(record, 0, record.Length);
                }
            }
            // Write the EOF markers.
            fs.WriteByte(0x1A); fs.WriteByte(0x1A);
            #endregion

            return(new DbfTable());
        }
 //***************************************************************************
 // Class Constructors
 //
 public DbfTable()
 {
     this._hdr = new DbfHeader(this);
 }
 public static DbfTable WriteDbf(DataTable dt, string filename, DbfHeader dbStruct)
 {
     using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
         return(DbfTable.WriteDbf(dt, fs, dbStruct));
 }
 public static DataTable LoadSchema(DbfHeader dbf)
 {
     DataTable dtRet = new DataTable();
     // Add the DBF fields to the DataTable
     foreach (DbfField fld in dbf.Fields)
     {
         DataColumn dc = new DataColumn(fld.FieldName.Trim());
         switch (fld.FieldDataType)
         {
             case DbfHeader.dBaseFieldType.Character:
                 dc.DataType = typeof(System.String);
                 dc.MaxLength = fld.FieldLength;
                 break;
             case DbfHeader.dBaseFieldType.Date:
                 dc.DataType = typeof(System.DateTime);
                 break;
             case DbfHeader.dBaseFieldType.Logical:
                 dc.DataType = typeof(System.Boolean);
                 break;
             case DbfHeader.dBaseFieldType.Memo:
                 dc.DataType = typeof(System.Int32);
                 break;
             case DbfHeader.dBaseFieldType.Numeric:
                 dc.DataType = typeof(System.String);
                 break;
         }
         dtRet.Columns.Add(dc);
     }
     return dtRet;
 }
        public static DbfTable WriteDbf(DataTable dt, FileStream fs, DbfHeader dbStruct)
        {
            // This string contains all the system data types that map to a
            //   particular DBF data type.  This saves from crazy-long
            //   "if" statements.
            string numericType = "Int16,Int32,Int64,Float,Double,Decimal";

            // This DbfField collection stores the info about the fields
            //   in the DBF file we're creating.
            DbfFieldCollection flds = new DbfFieldCollection();

            #region Write DBF Header
            // The first byte is the version identifier.
            // Here, we're specifying dBase IV.
            fs.WriteByte((byte)DbfHeader.dBaseType.dBase4WithOutMemo);
            // The next three bytes are the date that the file
            //   was last modified.
            DateTime dtNow = DateTime.Now;
            fs.Write(new byte[] { (byte)(dtNow.Year - 1900), (byte)dtNow.Month, (byte)dtNow.Day }, 0, 3);
            // The next four bytes contain a count of the number of records
            //   in the file.  NOTE:  these values are stored in reverse order.
            byte[] recCnt = Hex.GetBytes(Hex.ToHex(dt.Rows.Count).PadLeft(8, '0'));
            Array.Reverse(recCnt);
            fs.Write(recCnt, 0,4);
            // The next two bytes indicate the offset to the start of the
            //   actual data. NOTE: these values are stored in reverse  order.
            // The base header takes 32 bytes and each field header takes an
            //   additional 32 bytes.
            byte[] hdrSize = Hex.GetBytes(Hex.ToHex(32 + (dt.Columns.Count * 32)).PadLeft(4, '0'));
            Array.Reverse(hdrSize);
            fs.Write(hdrSize,0,2);
            // The next two bytes identify the size of each record. This number
            //   represents the sum of all field lengths + 1, due to the first
            //   byte of each record being a deletion flag. NOTE: these values
            //   are stored in reverse order.
            int recLen = 0;
            foreach (DataColumn dc in dt.Columns)
                recLen += (dc.MaxLength > 0) ? dc.MaxLength : 100;
            byte[] recSize = Hex.GetBytes(Hex.ToHex(recLen + 1).PadLeft(4, '0'));
            Array.Reverse(recSize);
            fs.Write(recSize,0,2);
            // The next sixteen bytes are not used, so we just fill the
            //   space with zeros.
            byte[] nullBytes = new byte[16]; nullBytes.Initialize();
            fs.Write(nullBytes,0,16);
            // The next byte is the compound index flag. This flag should be set to
            //   0x01h if a stuctural CDX file is attached to the database.
            // At present, I don't know how to write or read these, so I will
            //   hardcode this to 0x00h.
            fs.WriteByte(0x00);
            // The next three bytes are also not used, so fill with zeros.
            nullBytes = new byte[3]; nullBytes.Initialize();
            fs.Write(nullBytes,0,3);
            #endregion

            #region Write Field Headers
            // Now we parse and write the header for each column.
            int fldOffset = 0;
            if (dbStruct != null)
            {
                flds = dbStruct.Fields;
                byte[] fldsHdr = dbStruct.Fields.GetRawHeader();
                fs.Write(fldsHdr, 0, fldsHdr.Length);
            }
            else
            {
                foreach (DataColumn dc in dt.Columns)
                {
                    DbfHeader.dBaseFieldType fldType;
                    if (dc.DataType.Name == "DateTime")
                        fldType = DbfHeader.dBaseFieldType.Date;
                    else if (numericType.Contains(dc.DataType.Name))
                        fldType = DbfHeader.dBaseFieldType.Numeric;
                    else if (dc.DataType.Name == "Boolean")
                        fldType = DbfHeader.dBaseFieldType.Logical;
                    else
                        fldType = DbfHeader.dBaseFieldType.Character;

                    string fldName = dc.ColumnName.Substring(0, (dc.ColumnName.Length <= 10) ? dc.ColumnName.Length : 10);
                    //int fldSize = (dc.MaxLength > 0 || dc.DataType.Name != "String") ? dc.MaxLength : 100;
                    int fldSize = 50;
                    if (dc.DataType.Name == "DateTime")
                        fldSize = 8;
                    else if (dc.MaxLength > 0)
                        fldSize = dc.MaxLength;

                    flds.Add(new DbfField(fldName, fldType, fldOffset, fldSize, 0, dc.Ordinal));
                    fldOffset += fldSize;
                }
                byte[] fldsHdr = flds.GetRawHeader();
                fs.Write(fldsHdr, 0, fldsHdr.Length);
            }
            #endregion

            #region Write DBF Data
            foreach (DataRow dr in dt.Rows)
            {
                // The first byte of every record is the deletion flag.
                fs.WriteByte(0x00);
                // Convert each value to a byte array & add it to the buffer.
                for (int i = 0; i < dbStruct.Fields.Count; i++)
                {
                    byte[] record = new byte[0];
                    if (flds[i].FieldDataType == DbfHeader.dBaseFieldType.Date)
                    {
                        try
                        { record = Array.ConvertAll<Char, Byte>(((DateTime)dr[i]).ToString("yyyyMMdd").ToCharArray(), new Converter<Char, Byte>(Convert.ToByte)); }
                        catch (InvalidCastException)
                        { record = Array.ConvertAll<Char, Byte>("        ".ToCharArray(), new Converter<Char, Byte>(Convert.ToByte)); }
                    }
                    else if (flds[i].FieldDataType == DbfHeader.dBaseFieldType.Memo)
                    {
                        record = Array.ConvertAll<Char, Byte>("00000000".ToCharArray(), new Converter<char, byte>(Convert.ToByte));
                    }
                    else
                        record = Array.ConvertAll<Char, Byte>(dr[i].ToString().PadRight(flds[i].FieldLength, ' ').ToCharArray(), new Converter<Char, Byte>(Convert.ToByte));
                    fs.Write(record, 0, record.Length);
                }
            }
            // Write the EOF markers.
            fs.WriteByte(0x1A); fs.WriteByte(0x1A);
            #endregion

            return new DbfTable();
        }
 //***************************************************************************
 // Class Constructors
 // 
 public DbfTable()
 {
     this._hdr = new DbfHeader(this);
 }
 public static DbfTable WriteDbf(DataTable dt, string filename, DbfHeader dbStruct)
 {
     using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
         return DbfTable.WriteDbf(dt, fs, dbStruct);
 }
Exemple #10
0
 /// <summary>
 /// Retursn the System.Type equivalent to the supplied DbfHeader.dBaseFieldType.
 /// </summary>
 /// <param name="fldType">A DbfHeader.dBaseFieldType value to convert from.</param>
 /// <returns>An equivalent System.Type object.</returns>
 public static Type GetSystemDataType(DbfHeader.dBaseFieldType fldType)
 {
     switch (fldType)
     {
         case DbfHeader.dBaseFieldType.Logical:
             return typeof(System.Boolean);
         case DbfHeader.dBaseFieldType.Date:
             return typeof(System.DateTime);
         case DbfHeader.dBaseFieldType.DateTime:
             return typeof(System.DateTime);
         case DbfHeader.dBaseFieldType.Timestamp:
             return typeof(System.DateTime);
         case DbfHeader.dBaseFieldType.Memo:
             return typeof(System.String);
         case DbfHeader.dBaseFieldType.Numeric:
             return typeof(System.String);
         case DbfHeader.dBaseFieldType.Character:
             return typeof(System.String);
         case DbfHeader.dBaseFieldType.Unknown:
             return typeof(System.Object);
         case DbfHeader.dBaseFieldType.Long:
             return typeof(System.Int64);
         case DbfHeader.dBaseFieldType.Binary:
             return typeof(System.Int64);
         case DbfHeader.dBaseFieldType.AutoIncrement:
             return typeof(System.Int64);
         case DbfHeader.dBaseFieldType.Picture:
             return typeof(System.Byte[]);
         case DbfHeader.dBaseFieldType.FloatingPoint:
             return typeof(System.Double);
     }
     return typeof(System.String);
 }