public MDXFile(string dbfFile, ZipHelper _ziphelper, char DirSeperator, bool ReadOnly) { this.boolReadOnly = ReadOnly; this.objMDXEntrys = new List<MDX>(MAX_TAGS); short i; this.strName = Path.GetDirectoryName(dbfFile) + DirSeperator + Path.GetFileNameWithoutExtension(dbfFile) + ".mdx"; if (_ziphelper.FileExists(this.strName)) { BinaryReader mdxReader = null; try { byte[] buffer; GCHandle handle; this.objFileStream = _ziphelper.GetReadStream(this.strName); //Create a Binary Reader for the MDX file mdxReader = new BinaryReader(objFileStream); byte[] completeBuffer = mdxReader.ReadBytes((int) _ziphelper.GetStreamLength(this.strName, objFileStream)); mdxReader.Close(); mdxReader = new BinaryReader(new MemoryStream(completeBuffer), ASCIIEncoding.ASCII); // Marshall the header into a MDXHeader structure buffer = mdxReader.ReadBytes(Marshal.SizeOf(typeof (MDXHeader))); handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); this.objHeader = (MDXHeader) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof (MDXHeader)); handle.Free(); //Read the Key Nodes for (i = 0; i < objHeader.numberOfTagsInUse; i++) { int StreamStartPosition = Marshal.SizeOf(typeof (MDXHeader)); StreamStartPosition += (this.objHeader.lengthOfTag*i); if (i < objHeader.numberOfTagsInUse) { MDX newMDX = new MDX(i); this.objMDXEntrys.Add(newMDX); newMDX.Read(mdxReader, this.objHeader.lengthOfTag, StreamStartPosition); } else { objMDXEntrys.Add(null); } } } catch (Exception e) { Debug.WriteLine(e.Message); } finally { mdxReader.Close(); } } }
/// <summary> /// This Function Writes directly to a DBF File. /// It reads the Field list, and writes to the correct position. /// To access the deleted flag, use DELETED_FLAG as column Name /// </summary> /// <param name="dbfFile"></param> /// <param name="column"></param> /// <param name="row"></param> /// <param name="value"></param> /// <param name="ziphelper"></param> /// <param name="dirSeperator"></param> /// <returns></returns> public static bool WriteValue(string dbfFile, string column, int row, object value, ZipHelper ziphelper, char dirSeperator) { //if (zipfile != null) // throw new Exception("Write to Zipped Files is not supported!"); int bytesToRecordStart = 0; long start = DateTime.Now.Ticks; // If there isn't even a file, just return an empty DataTable if ((false == ziphelper.FileExists(dbfFile))) { return false; } BinaryReader br = null; BinaryWriter bw = null; try { // Read the header into a buffer Stream tmpStream = ziphelper.GetReadStream(dbfFile); br = new BinaryReader(tmpStream); byte[] completeBuffer = br.ReadBytes((int)ziphelper.GetStreamLength(dbfFile, tmpStream)); tmpStream.Close(); br.Close(); br = new BinaryReader(new MemoryStream(completeBuffer)); byte[] buffer = br.ReadBytes(Marshal.SizeOf(typeof(DBFHeader))); // Marshall the header into a DBFHeader structure GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); DBFHeader header = (DBFHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(DBFHeader)); handle.Free(); // Read in all the field descriptors. Per the spec, 13 (0D) marks the end of the field descriptors ArrayList fields = new ArrayList(); while ((13 != br.PeekChar())) { buffer = br.ReadBytes(Marshal.SizeOf(typeof(FieldDescriptor))); handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); fields.Add((FieldDescriptor)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(FieldDescriptor))); handle.Free(); } char writeFieldType = ' '; int writeFieldLength = 0; foreach (FieldDescriptor field in fields) { writeFieldType = (char)field.fieldType; writeFieldLength = field.fieldLen; if (field.fieldName == column) break; bytesToRecordStart += field.fieldLen; } br.Close(); Stream strm = ziphelper.GetWriteStream(dbfFile); bw = new BinaryWriter(strm); if (column != "DELETED_FLAG") bytesToRecordStart++; else bytesToRecordStart = 0; (/*(FileStream)*/ bw.BaseStream).Seek(header.headerLen + row*header.recordLen + bytesToRecordStart, SeekOrigin.Begin); if (column == "DELETED_FLAG") bw.Write((bool) value ? Encoding.ASCII.GetBytes("*") : Encoding.ASCII.GetBytes(" ")); else { /* number = Encoding.ASCII.GetString(recReader.ReadBytes(field.fieldLen)); switch (field.fieldType) { case (byte)'N': if (number.IndexOf(".") > -1) { col = new DataColumn(field.fieldName, typeof(decimal)); } else { col = new DataColumn(field.fieldName, typeof(int)); } break; case (byte)'C': col = new DataColumn(field.fieldName, typeof(string)); break; case (byte)'T': // You can uncomment this to see the time component in the grid //col = new DataColumn(field.fieldName, typeof(string)); col = new DataColumn(field.fieldName, typeof(DateTime)); break; case (byte)'D': col = new DataColumn(field.fieldName, typeof(DateTime)); break; case (byte)'L': col = new DataColumn(field.fieldName, typeof(bool)); break; case (byte)'F': col = new DataColumn(field.fieldName, typeof(Double)); break; case (byte)'M': //Field Type Memo... col = new DataColumn(field.fieldName, typeof(byte[])); //col = new DataColumn(field.fieldName, typeof(string)); break; }*/ switch (writeFieldType) { case 'N': bw.Write(Encoding.ASCII.GetBytes(value.ToString().PadLeft(writeFieldLength, ' '))); break; case 'C': bw.Write(Encoding.ASCII.GetBytes(value.ToString().PadRight(writeFieldLength, ' '))); break; default: //br.Close(); return false; } } ziphelper.WriteBackStream(dbfFile, strm); bw.Close(); } finally { if (br != null) br.Close(); if (bw != null) bw.Close(); } return true; }
private static void OpenMemoFile(string dbfFile, ZipHelper ziphelper, char dirSeperator) { string dbtFile = Path.GetDirectoryName(dbfFile) + dirSeperator + Path.GetFileNameWithoutExtension(dbfFile) + ".dbt"; if (ziphelper.FileExists(dbtFile)) { dbtReader = null; try { //dbtReader = new BinaryReader(new FileStream(dbtFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); //dbtReader=new BinaryReader(ZipHelper.GetReadStream(zipfile, dbtFile)); Stream tmpStream = ziphelper.GetReadStream(dbtFile); dbtReader = new BinaryReader(tmpStream); byte[] completeBuffer = dbtReader.ReadBytes((int)ziphelper.GetStreamLength(dbtFile, tmpStream)); dbtReader.Close(); dbtReader = new BinaryReader(new MemoryStream(completeBuffer)); // Read the header into a buffer byte[] buffer = dbtReader.ReadBytes(Marshal.SizeOf(typeof(DBTHeader))); // Marshall the header into a DBTHeader structure GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); DBTHeader header = (DBTHeader) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof (DBTHeader)); handle.Free(); memoBlockLength = header.blockLength; } catch(Exception) { throw; } } }
public static DataTable ReadDBF(string dbfFile, ZipHelper _ziphelper, char DirSeperator) { long start = DateTime.Now.Ticks; DataTable dt = new DataTable(); BinaryReader recReader; DataRow row; int fieldIndex; // If there isn't even a file, just return an empty DataTable if ((false == _ziphelper.FileExists(dbfFile))) { return dt; } BinaryReader br = null; openMemoFile(dbfFile, _ziphelper, DirSeperator); readMDXFile(dbfFile, _ziphelper, DirSeperator); //Dictionary<int, byte[]> memoLookup = ReadDBT(dbfFile); try { // Read the header into a buffer //br = new BinaryReader(new FileStream(dbfFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); Stream tmpStream = _ziphelper.GetReadStream(dbfFile); br = new BinaryReader(tmpStream); byte[] completeBuffer = br.ReadBytes((int)_ziphelper.GetStreamLength(dbfFile, tmpStream)); tmpStream.Close(); br.Close(); br = new BinaryReader(new MemoryStream(completeBuffer)); byte[] buffer = br.ReadBytes(Marshal.SizeOf(typeof(DBFHeader))); // Marshall the header into a DBFHeader structure GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); DBFHeader header = (DBFHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(DBFHeader)); handle.Free(); // Read in all the field descriptors. Per the spec, 13 (0D) marks the end of the field descriptors ArrayList fields = new ArrayList(); while ((13 != br.PeekChar())) { buffer = br.ReadBytes(Marshal.SizeOf(typeof(FieldDescriptor))); handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); fields.Add((FieldDescriptor)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(FieldDescriptor))); handle.Free(); } // Read in the first row of records, we need this to help determine column types below (br.BaseStream).Seek(header.headerLen + 1, SeekOrigin.Begin); buffer = br.ReadBytes(header.recordLen); recReader = new BinaryReader(new MemoryStream(buffer)); // Create the columns in our new DataTable DataColumn col = null; dt.Columns.Add(new DataColumn("DELETED_FLAG", typeof(bool))); foreach (FieldDescriptor field in fields) { byte[] NumberByteArray = recReader.ReadBytes(field.fieldLen); switch (field.fieldType) { case dBaseType.N: if (dBaseConverter.N_IsDecimal(NumberByteArray)){ col = new DataColumn(field.fieldName, typeof(decimal)); }else{ col = new DataColumn(field.fieldName, typeof(int)); } break; case dBaseType.C: col = new DataColumn(field.fieldName, typeof(string)); break; case dBaseType.T: col = new DataColumn(field.fieldName, typeof(DateTime)); break; case dBaseType.D: col = new DataColumn(field.fieldName, typeof(DateTime)); break; case dBaseType.L: col = new DataColumn(field.fieldName, typeof(bool)); break; case dBaseType.F: col = new DataColumn(field.fieldName, typeof(Double)); break; case dBaseType.M: //Field Type Memo... col = new DataColumn(field.fieldName, typeof(byte[])); break; } dt.Columns.Add(col); } // Skip past the end of the header. (br.BaseStream).Seek(header.headerLen, SeekOrigin.Begin); // Read in all the records for (int counter = 0; counter <= header.numRecords - 1; counter++) { // First we'll read the entire record into a buffer and then read each field from the buffer // This helps account for any extra space at the end of each record and probably performs better buffer = br.ReadBytes(header.recordLen); recReader = new BinaryReader(new MemoryStream(buffer)); // All dbf field records begin with a deleted flag field. Deleted - 0x2A (asterisk) else 0x20 (space) //if (recReader.ReadChar() == '*') //{ // continue; //} // Loop through each field in a record fieldIndex = 0; row = dt.NewRow(); char delflg = recReader.ReadChar(); if (delflg == '*') row[0] = true; else row[0] = false; foreach (FieldDescriptor field in fields) { switch (field.fieldType) { case dBaseType.N: // Number byte[] NumberBytes = recReader.ReadBytes(field.fieldLen); if (dBaseConverter.N_IsDecimal(NumberBytes)) { row[fieldIndex + 1] = dBaseConverter.N_ToDecimal(NumberBytes); } else { row[fieldIndex + 1] = dBaseConverter.N_ToInt(NumberBytes); } break; case dBaseType.C: // String row[fieldIndex + 1] = dBaseConverter.C_ToString( recReader.ReadBytes(field.fieldLen)); break; case dBaseType.M: // Memo row[fieldIndex + 1] = ReadMemoBlock(dBaseConverter.N_ToInt(recReader.ReadBytes(field.fieldLen))); break; case dBaseType.D: // Date (YYYYMMDD) DateTime DTFromFile = dBaseConverter.D_ToDateTime(recReader.ReadBytes(8)); if (DTFromFile == DateTime.MinValue) { row[fieldIndex + 1] = System.DBNull.Value; } else { row[fieldIndex] = DTFromFile; } break; case dBaseType.T: row[fieldIndex + 1] = dBaseConverter.T_ToDateTime(recReader.ReadBytes(8)); break; case dBaseType.L: // Boolean (Y/N) row[fieldIndex + 1] = dBaseConverter.L_ToBool(recReader.ReadByte()); break; case dBaseType.F: row[fieldIndex + 1] = dBaseConverter.F_ToDouble(recReader.ReadBytes(field.fieldLen)); break; } fieldIndex++; } recReader.Close(); dt.Rows.Add(row); } } catch { throw; } finally { if (null != br) { br.Close(); } if (dbtReader != null) { dbtReader.Close(); dbtReader = null; } } long count = DateTime.Now.Ticks - start; return dt; }