Динамическая структура для хранения типизированных данных - C#
Формулировка задачи:
Дано:
ini-файл со следующей структурой
раздел 1
список таблиц таблица 1 ... таблица j
таблица 1 ключ_1,значение_1 ключ_1,значение_1
... ... ...
таблица n ключ_m,значение_m ключ_l,значение_l
...
раздел k
список таблиц таблица 1 ...
таблица 1 ключ_1,значение_1
... ...
таблица j ключ_i,значение_i
по сути это схема репликации баз данных: раздел это одна база данных с таблицами обозначенными в списке таблиц, а ключ,значение описание имен и типов столбцов.
Имена таблиц в различных разделах могут совпадать, ключи в различных таблицах могут совпадать
В зависимости от подписки на получаемую информацию может изменяться количество разделов и количество таблиц в них.
Программа не должна заранее знать ничего о названиях разделов, таблиц и т.д.
Вопрос: Как считать эти данные из файла понятно, но в какую структуру и как сохранять?
Вопрос: Как с
Поскольку движок автоматически удаляет "лишние" пробелы, повторю несколько в другом виде:
Дано:
ini-файл со следующей структурой
[раздел: name1]
;список таблиц
table=table_1
...
table=table_n
[table:name1:table_1]
field=key_1,value_1
...
field=key_j,value_j
[раздел: nameN]
;список таблиц
table=table_1
...
table=table_m
[table:nameN:table_1]
field=key_1,value_1
...
field=key_l,value_l
по сути это схема репликации баз данных: раздел это одна база данных с таблицами обозначенными в списке таблиц, а ключ,значение описание имен и типов столбцов.
Имена таблиц в различных разделах могут совпадать, ключи в различных таблицах могут совпадать
В зависимости от подписки на получаемую информацию может изменяться количество разделов и количество таблиц в них.
Программа не должна заранее знать ничего о названиях разделов, таблиц и т.д.
Вопрос: Как считать эти данные из файла понятно, но в какую структуру и как сохранять?
Решение задачи: «Динамическая структура для хранения типизированных данных»
textual
Листинг программы
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; namespace ConsoleApplication { internal class Program { private static void Main() { var parser = new Parser(@"D:\forts_scheme.ini.txt", Encoding.ASCII); var timer = new Stopwatch(); timer.Start(); var data = parser.Parsing(); timer.Stop(); Console.WriteLine("Time of parsing: {0} ms", timer.ElapsedMilliseconds); Console.WriteLine("Test:"); foreach (var scheme in data) { Console.WriteLine("Scheme: {0}", scheme.Key); foreach (var table in scheme.Value) Console.WriteLine("The table {0} has {1} fields", table.Key, table.Value.Count()); } Console.WriteLine("Example of first field:"); var firstScheme = data.First(); var firstTable = firstScheme.Value.First(); var firstField = firstTable.Value.First(); Console.WriteLine("{0} -> {1} -> {2} = {3}", firstScheme.Key, firstTable.Key, firstField.Key, firstField.Value); } } public class Parser { private static readonly Regex schemeRegex = new Regex(@"\[dbscheme:(.+)\]", RegexOptions.Compiled); private static readonly Regex tableRegex = new Regex(@"\[table:(.+):(.+)\]", RegexOptions.Compiled); private static readonly Regex fieldRegex = new Regex(@"field\=(.+),(.+)", RegexOptions.Compiled); private readonly string path; private readonly Encoding encoding; private Dictionary<string, Section> schemes; private string scheme; private string table; public Parser(string path, Encoding encoding) { this.path = path; this.encoding = encoding; } public Dictionary<string, Section> Parsing() { schemes = new Dictionary<string, Section>(); using (var reader = new StreamReader(path, encoding)) { string line; var entityType = EntityType.Scheme; while ((line = reader.ReadLine()) != null) switch (entityType) { case EntityType.Scheme: if (CheckScheme(line)) entityType = EntityType.Table; break; case EntityType.Table: if (CheckTable(line)) entityType = EntityType.Field; break; case EntityType.Field: if (!CheckField(line) && !CheckTable(line) && CheckScheme(line)) entityType = EntityType.Table; break; } } return schemes; } private bool CheckScheme(string line) { var match = schemeRegex.Match(line); if (match.Success) schemes.Add(match.Groups[1].Value, new Section()); return match.Success; } private bool CheckTable(string line) { var match = tableRegex.Match(line); if (match.Success) { scheme = match.Groups[1].Value; table = match.Groups[2].Value; schemes[scheme].AddTable(table); } return match.Success; } private bool CheckField(string line) { var match = fieldRegex.Match(line); if (match.Success) schemes[scheme].AddFieldToTable(table, match.Groups[1].Value, match.Groups[2].Value); return match.Success; } private enum EntityType { Scheme, Table, Field } } public class Section : IEnumerable<KeyValuePair<string, Table>> { private readonly Dictionary<string, Table> tables = new Dictionary<string, Table>(); public void AddTable(string name) { tables.Add(name, new Table()); } public void AddFieldToTable(string name, string key, string value) { tables[name].AddField(key, value); } public Table GetTable(string name) { return tables[name]; } public IEnumerator<KeyValuePair<string, Table>> GetEnumerator() { return ((IEnumerable<KeyValuePair<string, Table>>)tables).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } public class Table : IEnumerable<Field> { private readonly Dictionary<string, string> fields = new Dictionary<string, string>(); public void AddField(string key, string value) { fields.Add(key, value); } public string GetField(string key) { return fields[key]; } public IEnumerator<Field> GetEnumerator() { return fields.Select(field => new Field(field.Key, field.Value)).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } public struct Field { public Field(string key, string value) : this() { Key = key; Value = value; } public string Key { get; set; } public string Value { get; set; } } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д