C# Разрезать текстовый файл по разделителям и сохранить в множество файлов

226
13 апреля 2018, 14:31

Вопрос: Есть 1 текстовый файл, в котором указаны пути файлов. В списке нет разделителей типа ; или каких либо других. В качестве условного разделителя используется определенное имя файла. Пример: C:\===01====.txt C:\qwerty.txt C:\asdfg.txt C:\===02===.txt C:\zxcvb.txt //....так далее Там где встречаются строки формата - C:\===01====.txt - это и есть разделитель. Будущее имя файла получаем из него методом удаления всего лишнего. Т.е. имя файла будет 01.txt

Я понимаю что файл нужно считать стримридером, в цикле while получать значения. И вот тут собственно вопрос: Если использовать Dictionary - где ключом будет полученное имя файла, например 01.txt, то как потом заполнить значения для параметра Value. Получать последний ключ словаря не есть хорошая идея. И для Dictionary для параметра Value следует использовать просто string с "\n" или лучше массив строк?

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

Извините если вопрос тупой, но нормальной реализации простой задачи я не нашел, а с тем как адекватно заполнить Dictionary (или может имеет смысл что то другое использовать?) я пока не разобрался.

Answer 1

По сути, вам надо читать построчно и определять, если это терминальный файл - то создавать новую коллекцию и писать её в словарь. Если это обычный файл = то добавлять его в текущую коллекцию. Примерный код (запускать на свой страх и риск)

var fname = @"C:\.....";
var dict = new Dictionary<string, List<string>>();
var current = string.Empty; 
var regex = new Regex(@"C:\\=+[0-9]+=+\.txt");
foreach (var line in File.ReadLines(fname))
{
    if (regex.IsMatch(line))
    {
        current = line.Replace("=", string.Empty);
        dict.Add(current, new List<string>());
    }
    else
    {
        dict[current].Add(line);
    }
}
// Вывод, что напарсили
foreach (var file in dict.OrderBy(x=>x.Key))
{
    Console.WriteLine(file.Key);
    foreach (var subfile in file.Value)
    {
        Console.WriteLine($"\t{subfile}");
    }
}

Вывод на ваших данных будет

C:\01.txt
  C:\qwerty.txt
  C:\asdfg.txt
C:\02.txt
  C:\zxcvb.txt  
Answer 2

Вот что у меня вышло. Я записываю ключом имя файла, а значением List того, что между разделителями. Примерно так это и пытался сделать сначала и благодаря подсказке @tym32167 смог понять что и как добавлять. Но возникла проблема с тем, что при выполнении кода, даже при условии что текстовик весит всего 14 Кб, программа на секунду-полторы, во время создания файлов и записи в них, залипает. Мне не кажется это нормальным, поэтому думаю как сделать все менее ресурсозатратным.

 Dictionary  <string, List<string>> MyDictionary = new Dictionary<string, List<string>> ();
        using (var sr = new StreamReader(@"C:\MyTextFile.txt", Encoding.GetEncoding("windows-1251")))
        {
            string line;
            string tempkey = "";
            while ((line = sr.ReadLine()) != null)
            {
                string templine;
                if (line.Contains("=========="))
                {
                    templine = line.Replace("==========", "").Replace(".txt", "").Replace(@"J:\SOMEPATH\", "").Replace("_", "-");
                    templine += "music";
                    tempkey = templine;
                    MyDictionary.Add(templine, new List<string>());
                }
                else
                {
                    if (MyDictionary.ContainsKey(tempkey))
                    {
                       MyDictionary[tempkey].Add(line + "\n");
                    }
                }
            }
        }
        var encoding = Encoding.GetEncoding("windows-1251");
        foreach (var FilesName in MyDictionary.Keys)
        {
            var fileName = @"C:\DESTINATIONFOLDER\" + FilesName + ".txt";
            foreach (var value in MyDictionary[FilesName])
            {
                File.AppendAllText(fileName, value, encoding);
            }
        }
READ ALSO
Не понятно, как работать с JSON на C# [дубликат]

Не понятно, как работать с JSON на C# [дубликат]

На данный вопрос уже ответили:

218
Сохранить файл в другую директорию

Сохранить файл в другую директорию

У меня есть директория (допустим string pathFile = P:\Database\new) , в которую нужно копировать файл, выбранный пользователемНачал писать:

240
Ликвидация формы, почему? [требует правки]

Ликвидация формы, почему? [требует правки]

При закрытии второй формы и повторном ее открытии вылетает ошибка с тем что Доступ к ликвидированному объекту не возможен?!? Раньше все норм...

196
Microsoft Visual Studio 2015 с mssql server 2012

Microsoft Visual Studio 2015 с mssql server 2012

ЗдравствуйтеРаньше пользовался visual studio 2013

177