No Description

akapralov f55995cf2c lab 10 months ago
.idea f55995cf2c lab 10 months ago
kapralov13 f55995cf2c lab 10 months ago
kapralov13.sln f55995cf2c lab 10 months ago
readme.md f55995cf2c lab 10 months ago

readme.md

Конспект по теме "Форматы файлов"

CSV

CSV - текстовый формат для представления табличных данных, где строки таблицы соответствуют строкам текста с полями,
разделенными запятыми. Хоть идея использования запятых для разделения полей очевидна,
возникают проблемы при наличии запятых или переводов строк в исходных данных.
Решение - *заключение данных в кавычки*, но это может вызвать проблемы при наличии кавычек в исходных данных.
Термин ```"CSV"``` иногда используется для форматов с другими разделителями, как символ табуляции или точка с запятой.
Многие приложения позволяют *выбирать символы разделителя* и *кавычек*`

Дальше всё по инструкции (создал csv файл и заупстил код).

using System.Globalization;
using CsvHelper;
using CsvHelper.Configuration;

using (var reader = new StreamReader("./test.csv")) {
    using (var csv = new CsvReader(
               reader, CultureInfo.InvariantCulture))
    {
        var records = csv.GetRecords<Foo>();
        foreach (var record in records) {
            Console.WriteLine("{0}, {1}", record.description, record.value);
        }
    }
}

public class Foo
{
    public string description { get; set; }
    public double value { get; set; }
}
строка с пробелами, 123,15
строка      
с переносом 
строки, 456

Запись в CSV

// использую не стандартный формат
var config = new CsvConfiguration(
    CultureInfo.InvariantCulture) { 
        Delimiter = ";", 
        HasHeaderRecord = false };

// создаю тестовые данные
var records = new List<Foo>
{
    new Foo { 
        description ="тест записи\nмногострочного текста",
        value = 12.34 },
    new Foo { 
        description = "просто, текст, с запятыми", 
        value = 0 }
};

using (var writer = new StreamWriter("./test3.csv"))
using (var csv = new CsvWriter(writer, config))
{
    csv.WriteRecords(records);
}

Вывод записи:

"тест записи
многострочного текста";12.34
просто, текст, с запятыми;0

Process finished with exit code 0.

Различия в культурной среде

В русской культурной среде в качестве разделителя разрядов в числах с плавающей запятой используется запятая. Поэтому вполне может попасться csv файл, в котором в числах разделитель запятая.

csv
"строка с пробелами";123,15
"строка
с переносом 
строки";456

Разделитель полей мы менять умеем, но как быть с форматом чисел?

Нужно задать нужную культурную среду:

cs
var config = new CsvConfiguration(
    new CultureInfo("ru-RU")) { 
        Delimiter = ";", 
        HasHeaderRecord = false };

JSON

json
{
  "firstname": "Михаил",
  "lastname": "Максимов",
  "phone": "+79201234567",
  "city": "Москва",
  "age": 37,
  "bonus": 2000,
  "prev": [
    "Кроссовки",
    "Турник",
    "Зимняя куртка"
  ]
}

Newtonsoft.Json

cs
var person = new Person
{
    name = "Имя",
    age = 18,
    date = "2024-03-07"
};

string json = JsonConvert.SerializeObject(
    person, Formatting.Indented);

Console.WriteLine(json);

Должны получить что-то подобное:

json
{
    "name": "Имя",
    "age":18,
    "date":"2024-03-07"
}

Работа с JSON. DataContractJsonSerializer.

cs
[DataContract]
internal class Person
{
    [DataMember]
    public string name;

    [DataMember]
    public int age;

    [DataMember]
    public DateTime date;
}

Сериализация (Преобразование объекта в JSON-строку)

cs
var PersonList = new List<Person>() {
    new Person {name="Иванов", age=25, date=new DateTime(2021,1,1)},
    new Person {name="Петров", age=35, date=new DateTime(2021,1,2)}
};

// создаем объект сериализатора, указав, что на входе 
// будет МАССИВ объектов Person
var Serializer = new DataContractJsonSerializer(typeof(Person[]));

using (var streamWriter = new StreamWriter("test1.json"))
{
    Serializer.WriteObject(
        streamWriter.BaseStream,
        // Преобразуем список (List) объектов в МАССИВ
        PersonList.ToArray()
    );
}
json
[{"age":25,"date":"\/Date(1609448400000+0300)\/","name":"Иванов"},{"age":35,"date":"\/Date(1609534800000+0300)\/","name":"Петров"}]

Десериализация (Преобразование JSON-строки в объект)

cs
[DataContract]
internal class Person
{
    // создаем приватную переменную для хранения даты
    private DateTime privateDate;

    [DataMember]
    public string name { get; set; }

    [DataMember]
    public string age { get; set; }

    // создаем ПРИВАТНОЕ СТРОКОВОЕ свойство и с помощью атрибутов меняем ему имя для сериализатора
    [DataMember(Name = "date")]
    private string StringDate {
        get {
            return privateDate.ToString("yyyy-MM-dd");
        }
        set {
            // 2021-03-21
            // 0123456789
            privateDate = new DateTime(
                Convert.ToInt32(value.Substring(0, 4)),
                Convert.ToInt32(value.Substring(5, 2)),
                Convert.ToInt32(value.Substring(8, 2))
            );
        } 
    }

    // публичное свойство "дата" скрываем от сериализатора
    [IgnoreDataMember]
    public DateTime date { 
        get { return privateDate; }
        set { privateDate = value;  } 
    }
}

Вариант попроще

cs
// целевые классы нам по прежнему нужны, но уже без всяких аннотаций
internal class MaterialTC
{
    public string Title { get; set; }
    public int Count { get; set; }
}

internal class Notice
{
    public Material[] data;
}

internal class Answer
{
    public Notice notice;
}

// в месте, где нам нужно распарсить JSON создаем сериализатор и разбираем строку
var serializer = new JavaScriptSerializer();
var answer = serializer.Deserialize<Answer>("тут ваша JSON-строка");

// и ВСЁ