Я бы использовал CSVHelper
библиотеку для чтения / записи CSV, поскольку это полноценная хорошая библиотека. Для этого вы должны объявить класс для хранения ваших данных, и его имена свойств должны совпадать с именами столбцов вашего CSV-файла.
public class ImageData
{
public int ImgID { get; set; }
public double Longitude { get; set; }
public double Latitude { get; set; }
public double Altitude { get; set; }
}
Затем, чтобы увидеть, равны ли две строки, вам нужно посмотреть если каждое свойство в каждой строке в одном файле соответствует другому. Вы можете сделать это, просто сравнивая свойства, но я бы предпочел написать для этого средство сравнения, например:
public class ImageDataComparer : IEqualityComparer<ImageData>
{
public bool Equals(ImageData x, ImageData y)
{
return (x.Altitude == y.Altitude && x.Latitude == y.Latitude && x.Longitude == y.Longitude);
}
public int GetHashCode(ImageData obj)
{
unchecked
{
int hash = (int)2166136261;
hash = (hash * 16777619) ^ obj.Altitude.GetHashCode();
hash = (hash * 16777619) ^ obj.Latitude.GetHashCode();
hash = (hash * 16777619) ^ obj.Longitude.GetHashCode();
return hash;
}
}
}
Простое объяснение состоит в том, что мы переопределяем метод Equals()
и предписываем два экземпляра ImageData
class равны, если совпадают три значения свойств. Я немного покажу использование.
Часть чтения / записи CSV довольно проста (на странице справки библиотеки есть несколько хороших примеров и советов, прочтите, пожалуйста). Я могу написать два метода для чтения и записи, например:
public static List<ImageData> ReadCSVData(string filePath)
{
List<ImageData> records;
using (var reader = new StreamReader(filePath))
{
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
csv.Configuration.HasHeaderRecord = true;
records = csv.GetRecords<ImageData>().ToList();
}
}
return records;
}
public static void WriteCSVData(string filePath, List<ImageData> records)
{
using (var writer = new StreamWriter(filePath))
{
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(records);
}
}
}
Фактически вы можете написать общие c <T>
методы чтения / записи, чтобы эти два метода можно было использовать с разными классами, если это что-то полезно для вас.
Следующая важная часть. Сначала прочтите два файла в память, используя методы, которые мы только что определили.
var oldData = ReadCSVData(Path.Combine(Directory.GetCurrentDirectory(), "OldFile.csv"));
var newData = ReadCSVData(Path.Combine(Directory.GetCurrentDirectory(), "NewFile.csv"));
Теперь я могу go просмотреть каждую строку в «старых» данных и посмотреть, есть ли соответствующая запись в ' новые 'данные. Если это так, я беру идентификатор из новых данных и заменяю им идентификатор старых данных. Обратите внимание на использование написанного нами компаратора.
foreach (var line in oldData)
{
var replace = newData.FirstOrDefault(x => new ImageDataComparer().Equals(x, line));
if (replace != null && replace.ImgID != line.ImgID)
{
line.ImgID = replace.ImgID;
}
}
Затем просто перезапишите старый файл данных.
WriteCSVData(Path.Combine(Directory.GetCurrentDirectory(), "OldFile.csv"), oldData);
Результаты
Я использую упрощенную версию ваших данных, чтобы легко проверить наши результаты.
Старые данные
ImgID,Longitude,Latitude,Altitude
1,1,2,3
2,2,3,4
3,3,4,5
4,4,5,6
5,5,6,7
6,6,7,8
7,7,8,9
8,8,9,10
9,9,10,11
10,10,11,12
11,11,12,13
Новые данные
ImgID,Longitude,Latitude,Altitude
5702,1,2,3
5703,2,3,4
5704,3,4,5
5705,4,5,6
5706,5,6,7
5707,6,7,8
Сейчас наши ожидаемые результаты должны заключаться в том, что первые 6 строк старых файлов должны иметь обновленные идентификаторы, и вот что мы получим:
Обновленные старые данные
ImgID,Longitude,Latitude,Altitude
5702,1,2,3
5703,2,3,4
5704,3,4,5
5705,4,5,6
5706,5,6,7
5707,6,7,8
7,7,8,9
8,8,9,10
9,9,10,11
10,10,11,12
11,11,12,13