/// <summary> /// Compares two DBF files. /// Note: the algorithm relies on the fact that it is only possible to /// append records to a DBF file (i.e. no inserts in the middle of the /// file) and it is requires the older file is passed as the first /// argument. /// </summary> /// <param name="oldFilepath"> /// The path to the older DBF file to compare. /// </param> /// <param name="newFilepath"> /// The path to the newer DBF file to compare. /// </param> /// <returns> /// The <see cref="IEnumerable{T}"/> of the differences between the two files. /// </returns> public static IEnumerable<Diff> Compare(string oldFilepath, string newFilepath) { using (var reader1 = new DbfReader(oldFilepath)) using (var reader2 = new DbfReader(newFilepath)) { //// todo: check compatible schema var hasMore1 = reader1.Read(); var hasMore2 = reader2.Read(); while (hasMore1 && hasMore2) { var record1 = reader1.DbfRecord; var record2 = reader2.DbfRecord; var diff = Compare(record1, record2); switch (diff.Operation) { case Operation.Unmodified: hasMore1 = reader1.Read(); hasMore2 = reader2.Read(); break; case Operation.Modified: hasMore1 = reader1.Read(); hasMore2 = reader2.Read(); break; case Operation.Deleted: hasMore1 = reader1.Read(); break; } if (diff.Operation != Operation.Unmodified) { yield return diff; } if (hasMore1 || !hasMore2) { continue; } var index = record1.RecordIndex; while (reader2.Read()) { record2 = reader2.DbfRecord; var columnDiffs = new List<ColumnDiff>(); for (int columnIndex = 0; columnIndex < record1.ColumnCount; ++columnIndex) { var columnDiff = new ColumnDiff(columnIndex, record1[columnIndex], record2[columnIndex]); columnDiffs.Add(columnDiff); } yield return new Diff(Operation.Inserted, ++index, columnDiffs); } hasMore2 = false; } } }
/// <summary> /// The to CSV. /// </summary> /// <param name="filepath"> /// The file path. /// </param> public static void ToCsv(string filepath) { if (string.IsNullOrEmpty(filepath)) { return; } var destination = filepath.Replace(".DBF", ".csv"); using (Stream stream = File.Open(filepath, FileMode.Open, FileAccess.Read)) using (TextWriter writer = new StreamWriter(destination)) { var reader = new DbfReader(stream); while (reader.Read()) { var record = reader.DbfRecord; for (var i = 0; i < record.ColumnCount; ++i) { writer.Write(record[i].Trim()); if (i != record.ColumnCount - 1) { writer.Write(","); } } writer.WriteLine(); } writer.Flush(); } }