public void UpdateColumn(int col, Array values) { using (FileStream fs = new FileStream(this._file, FileMode.Open, FileAccess.ReadWrite)) { // Move to the start of the first row. this.MoveStreamToRow(0, fs); // Jump to the start of the field. this.MoveStreamToField(col, fs); // Then, write each value and then skip the size of a full // record, minus the updated field length, which should // put the Stream's position at the start of that same // field for the next record. int recSize = (this._hdr.RecordSize + 1) - this._hdr.Fields[col].FieldLength; foreach (object obj in values) { DbfTable.WriteDbfField(fs, this._hdr.Fields[col], obj); // If the total numer of bytes read does not match the determined // number of bytes to skip for each record, it means we hit // the end of the file. if (fs.Read(new byte[recSize], 0, recSize) != recSize) { break; } } // And set the LastUpdateDate value in the header. DbfTable.SetLastUpdateTime(fs); } }
public void DeleteRecord(long row) { using (FileStream srcDbf = new FileStream(this._file, FileMode.Open, FileAccess.Read)) using (BinaryReader br = new BinaryReader(srcDbf)) using (FileStream fs = new FileStream(Path.ChangeExtension(this._file, ".tmpDbf"), FileMode.Create, FileAccess.Write)) { // Copy the header data from fs.Write(br.ReadBytes(this._hdr.DataOffset - 2), 0, this._hdr.DataOffset - 2); // Copy all records prior to the one to be deleted. fs.Write(br.ReadBytes((int)((_hdr.RecordSize + 1) * row)), 0, (int)((_hdr.RecordSize + 1) * row)); // Now, skip the row to be deleted... br.ReadBytes(_hdr.RecordSize); // ...And write the rest of the file. fs.Write(br.ReadBytes((int)(br.BaseStream.Length - br.BaseStream.Position)), 0, (int)(br.BaseStream.Length - br.BaseStream.Position)); // Don't forget to update the record count in the header. DbfTable.UpdateRecordCount(fs, this._hdr.RecordCount - 1); this.OnRecordDeleted(EventArgs.Empty); // And set the last update time. DbfTable.SetLastUpdateTime(fs); } // Then move the 'tmpDbf' file to replace the existing DBF file. File.Move(this._file, Path.ChangeExtension(this._file, ".rsbak_" + DateTime.Now.ToString("yyyyMMddHHmmss"))); File.Move(Path.ChangeExtension(this._file, ".tmpDbf"), this._file); }
public void UpdateRecord(long row, Array values) { using (FileStream fs = new FileStream(this._file, FileMode.Open, FileAccess.ReadWrite)) { // If row '-1' was passed, it means insert, so move the cursor // to the end of the stream. Otherwise, move it // to the selected record number. if (row == -1) { fs.Position = fs.Length; } else { this.MoveStreamToRow(row, fs); } // Write the row data using the static method. DbfTable.WriteDbfRecord(fs, this._hdr.Fields, values); // If we added a record, we have to update the header to reflect this. DbfTable.UpdateRecordCount(fs, this._hdr.RecordCount + 1); this.OnRecordAdded(EventArgs.Empty); // And set the last update time. DbfTable.SetLastUpdateTime(fs); } }
/// <summary> /// Writes a single field of data to a DBF file using the provided Stream object. This method assumes the Stream object's write position is located at the position to begin writing. /// </summary> /// <param name="s">An initialized Stream object of a DBF file with the cursor position set to the beginning of the field to be written.</param> /// <param name="fld">A DbfField object detailing the structure of the field to be written to.</param> /// <param name="value">A System.Object value whose string representation will be written to the Stream.</param> public static void WriteDbfField(Stream s, DbfField fld, object value) { // Save the Stream's current position and the size of the field. long sPos = s.Position, sLen = fld.FieldLength + fld.DecimalLength; // Get the string value of the passed Object 'value' to be written. string val = string.Empty; if (value != null) { val = (value.GetType().Name == "DateTime") ? ((DateTime)value).ToString("yyyyMMdd") : value.ToString(); } // Create a byte array from the string representation of 'value'. byte[] buffer = Encoding.ASCII.GetBytes(val.Substring(0, System.Math.Min(fld.FieldLength, val.Length)).PadRight(fld.FieldLength, ' ')); // If the passed Stream object is a FileStream object, // then lock the bytes we're about to write to. if (s.GetType().FullName == "System.IO.FileStream") { ((FileStream)s).Lock(sPos, sLen); } // Write the byte buffer. If an error occurs, just throw it back // to the calling code, but don't forget to unlock the stream. try { s.Write(buffer, 0, buffer.Length); DbfTable.SetLastUpdateTime(s); } catch { throw; } finally { if (s.GetType().FullName == "System.IO.FileStream") { ((FileStream)s).Unlock(sPos, sLen); } s.Position = sPos; } }
public static void SetLastUpdateTime(Stream s) { DbfTable.SetLastUpdateTime(s, DateTime.Now); }