readme.md 6.0 KB

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

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 ="тест записи\многострочного текста",
        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": "+79179871337",
  "city": "Йошкар-Ола",
  "age": 22,
  "bonus": 2000,
  "prev": [
    "Кроссовки",
    "Турник",
    "Зимняя куртка"
  ]
}

Newtonsoft.Json

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

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

Console.WriteLine(json);

вывод:

json
{
    "name": "имя",
    "age":18,
    "date":"2024-03-17"
}

Работа с 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)}
};


var Serializer = new DataContractJsonSerializer(typeof(Person[]));

using (var streamWriter = new StreamWriter("test1.json"))
{
    Serializer.WriteObject(
        streamWriter.BaseStream,
        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;
}

var serializer = new JavaScriptSerializer();
var answer = serializer.Deserialize<Answer>("тут ваша JSON-строка");