Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
1 / 1 / 2
Регистрация: 02.10.2013
Сообщений: 76

Разбивка файла StreamWriter-ом на несколько файлов

17.01.2015, 15:48. Показов 2129. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую,
есть файл содержащий очень много строк и как бы разбитый на блоки строкой $$$$, надо:
1) этот файл разбить на несколько файлов например по 100 блоков.
т.е. надо начать записывать строки в файл1 и если сто раз встретилась строка $$$$, то последующие строки записывать в файл2 пока опять строка $$$$ не встретится 100 раз и так до конца файла.
2) при этом, если в одном блоке в любом месте встретилась строка #### то этот блок пропустить

нашел похожую , которая стримврайтером, похоже что, делает первую часть того, что мне надо, но не могу в ней разобраться, чтобы переделать код под себя.
тамошний код:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public void ProcessFile(string filename, string targetDirectory)
{
    using (var pool = new FilePool(targetDirectory))
    {
        foreach(var line in File.ReadLines(filename))
        {
            var parts = line.Split(';');
            pool.SaveInto(parts[7], parts[0] + ";" + parts[3]);
        }
    }
}
 
class FilePool : IDisposable
{
    Dictionary<string, StreamWriter> writers =
        new Dictionary<string, StreamWriter>();
 
    string prefix;
    public FilePool(string prefix)
    {
        this.prefix = prefix;
    }
 
    public void SaveInto(string id, string line)
    {
        var writer = Get(id);
        writer.WriteLine(line);
    }
 
    TextWriter Get(string id)
    {
        if (!writers.ContainsKey(id))
            InsertWriter(id);
        return writers[id];
    }
 
    void InsertWriter(string id)
    {
        var writer = new TextWriter(Path.Combine(prefix, id + ".d"));
        writer.WriteLine("Заголовок");
        writers.Add(id, writer);
    }
 
    public void Dispose()
    {
        foreach (var writer in writers.Values)
            writer.Dispose();
        writers.Clear();
    }
}
буду благодарен за любые подсказки!

Добавлено через 13 минут
пробовал (только не смейтесь) так, но не работает из-за того что имени переменной названия стримврайтера не присвоено значение:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
      StreamWriter writer;
       void partstrimwr()
        {
            StreamWriter writer = new StreamWriter(openFileDialog6.FileName.Replace(".sdf", "") + "DellAddFields-" + flnmbr + ".sdf"); 
          
        }
       //void swrcl()
       //{
       //  writer.Close();
       //}
        private void button45_Click(object sender, EventArgs e)
        {
            partstrimwr();
            using (StreamReader sr = new StreamReader(openFileDialog6.FileName, Encoding.Default)) //читаем файл
            {
                string line;
                while ((line = sr.ReadLine()) != null)//читаем до конца файла
                {
                     {
                         writer.WriteLine(line);
                        if (line.Contains("$$$$"))
                        {
                            stcnt++;
                            if ((stcnt % 100000) == 0)
                            {
                                flnmbr++;
                                textBox9.AppendText("\r\n" + DateTime.Now.ToString("HH:mm:ss") + "< flnmbr " + flnmbr +"\r\n");
                                partstrimwr();
                            }
                        }
                        writer.Close(); //закрываем Writer
                    }
                  }
 
                sr.Close(); //закрываем Reader
                mytimer1();
                textBox9.AppendText("\r\n" + DateTime.Now.ToString("HH:mm:ss") + "< SDF processing finished in: " + timer11 + "\r\nSDF has " + strcntfd + " structures\r\n\r\n");
            }
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
17.01.2015, 15:48
Ответы с готовыми решениями:

Разбивка одного текстового файла на несколько
Всем привет!) помогите пожалуйста , я хочу реализовать такую программу: Допустим имеется текстовый файл на 10231 строк. Надо...

Разбивка 16-ричного файла на несколько по "разделителю", возможно ли?
Возможно ли через батник разбить файл на несколько по &quot;разделителю&quot;? в моем случае разделителем служит 14000A00 , он должен присутствовать...

Разбивка List'a на несколько
Добрый вечер. Допустим у меня есть список из n элементов. Как мне его разбить на m списков по k элементов в каждом? (n = m*k)

8
286 / 192 / 56
Регистрация: 25.12.2012
Сообщений: 640
17.01.2015, 17:11
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
private void button45_Click(object sender, EventArgs e)
{
    string @out = openFileDialog6.FileName.Replace(".sdf", "");
    string @in = openFileDialog6.FileName;
    int flnmbr = 0;
    int stcnt = 0;
    string line;
    StreamWriter writer = new StreamWriter(@out + "DellAddFields-" + flnmbr + ".sdf");
 
    using (StreamReader sr = new StreamReader(@in, Encoding.Default)) //читаем файл
    {
        while ((line = sr.ReadLine()) != null)//читаем до конца файла
        {
            writer.WriteLine(line);
 
            if (line.Contains("$$$$"))
                if ((stcnt++ % 100000) == 0)
                {                           
                    textBox9.AppendText("\r\n" + DateTime.Now.ToString("HH:mm:ss") + "< flnmbr " + flnmbr++ + "\r\n");
                    writer.Close(); //закрываем Writer
                    writer = new StreamWriter(@out + "DellAddFields-" + flnmbr + ".sdf");
                }
        }
        textBox9.AppendText("\r\n" + DateTime.Now.ToString("HH:mm:ss") 
            + "< SDF processing finished in: " + timer11 + "\r\nSDF has " + strcntfd + " structures\r\n\r\n");
    }
}
Или так, через консольное приложение
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
unsafe static void Main(string[] args)
{
    //using System.Text.RegularExpressions;
    int counter = 0; 
 
    Regex r = new Regex(@"(?(   (?<=(\$\$\$\$)|^)    .*?  \#\#\#\#   .*?    \$\$\$\$     )
                              (?!)
                              |
                              ( 
                                (  (?<=(\$\$\$\$)|^)  .*?  \$\$\$\$  ){100}  
                                |  
                                (  (?<=(\$\$\$\$)|^)  .*?  \$\$\$\$  )+  
                              )
                          )",
       RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline);
 
    foreach (Match m in r.Matches(File.ReadAllText(@"in.txt")))
        File.WriteAllText("out" + counter++ + ".txt", m.Value);     
}
1
1 / 1 / 2
Регистрация: 02.10.2013
Сообщений: 76
17.01.2015, 19:17  [ТС]
разбираюсь, спасибо!
второй вариант не подходит, потому что при ReadAllText из файла размером 3 гига получаю аутофмемори
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
18.01.2015, 20:38
Лучший ответ Сообщение было отмечено Psilon как решение

Решение

tigorlab, попробуй, должно работать:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
        public static void SplitFile(string input, string output, string delimeter, string skipBlock)
        {
            var sb = new StringBuilder(8000);
            bool skip = false;
            int i = 0;
            foreach (string line in File.ReadLines(input))
            {
                if (line == delimeter)
                {
                    if (!skip)
                    {
                        File.WriteAllText(output + i++, sb.ToString());
                        sb.Clear().Length = 8000;
                    }
                    skip = false;
                }
                if (line == skipBlock)
                {
                    skip = true;
                }
                if (!skip)
                {
                    sb.AppendLine(line);
                }
            }
        }
примерно так:
C#
1
SplitFile("input.txt", "output.txt", "$$$$", "####");
0
1 / 1 / 2
Регистрация: 02.10.2013
Сообщений: 76
21.01.2015, 12:14  [ТС]
всем большое спасибо за помощь! допилил программу, может кому-то будет полезно - распишу что получилось в итоге.

к сожалению был глюк с почтой поэтому пропустил уведомление об ответе в теме, и поэтому тоже написал быдло-код который пропускает блок содержащий строку ####:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
private void button49_Click(object sender, EventArgs e)
{
    if (textBox13.Text != "")//значение("пропуск" маркер), наличие которого является условием пропуска данного блока
    {
        int isrgnt = 0, norgnt = 0;
        string line, sblock = "", sblock1 = "", isreagent;// обычное значение строки isreagent = "isreagent>\r\ntyes";
        isreagent = textBox13.Text.Replace(">", "").Replace("\r\n", "");
        textBox15.AppendText("\r\nReference value " + textBox13.Text.Replace("\r\n", " "));
 
        using (StreamReader sr = new StreamReader(openFileDialog7.FileName, Encoding.Default)) //читаем файл
        {
            using (StreamWriter writer = new StreamWriter(openFileDialog7.FileName.Replace(".sdf", "") + "NoReags.sdf"))
            {
                while ((line = sr.ReadLine()) != null)//читаем до конца файла
                {
                    sblock = sblock + line + "\r\n";
                    sblock1 = sblock1 + line.Replace(">", "").Replace("\r\n", "");//для проверки наличия "пропуск" маркера в блоке
 
                    if (line.Contains("$$$$"))
                    {
                        if (sblock1.Contains(isreagent.Replace("\r\n", "")))//если блок содержит "пропуск" маркер
                        {
                            sblock = "";
                            sblock1 = "";
                            isrgnt++;//счетчик пропущенных блоков
                        }
                        else//если в блоке нет маркера "пропуск" 
                        {
                            sblock = sblock.Replace("$$$$\r\n", "$$$$");//удаляем лишний переход на новую строку
                            writer.WriteLine(sblock);
                            sblock = "";
                            sblock1 = "";
                            norgnt++;//счетчик записанных блоков
                        }
                    }
                }
                writer.Close();
            }
            textBox15.AppendText("\r\n" + DateTime.Now.ToString("HH:mm:ss") + "< reagent " + isrgnt + ". no reagent " + norgnt + "\r\n");
        }
    }
    else
    {
        MessageBox.Show("Field and value not selecyed!", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}
Psilon, спасибо за красивую функцию, теперь посмотрев на пальцах как это работает стало понятно как в момент вызова функции задавать для нее определенные значения.
код для потоковой записи и одновременной разбивки на файлы от maxillion, не совсем правильно работал: у последнего файла стримврайтер не закрывался, а если число блоков в исходном файле было пропорционально заданному числу блоков на файл (например, 6 и 2) то создавался один пустой лишний файл, немного подправил, работает как надо:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
string[] filenumber = { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99" };       
private void button45_Click(object sender, EventArgs e)
{
    if (openFileDialog7.FileName != "")
    {
        string @out = openFileDialog7.FileName.Replace(".sdf", "");
        string @in = openFileDialog7.FileName;
        int flnmbr = 0, stcnt = 0, splstrcnt;
        string line;
        if (textBox14.Text != "")
        {
            splstrcnt = Convert.ToInt32(textBox14.Text);
            StreamWriter writer = new StreamWriter(@out + "-" + filenumber[0] + ".sdf"); //filenumber[0] = 01
            textBox15.AppendText("\r\n" + DateTime.Now.ToString("HH:mm:ss") + "< " + @out + "-" + filenumber[flnmbr] + ".sdf");
            using (StreamReader sr = new StreamReader(@in, Encoding.Default)) //читаем файл
            {
                while (sr.Peek() > -1 /*(line = sr.ReadLine()) != null*/)//читаем до конца файла
                {
                    line = sr.ReadLine();
                    writer.WriteLine(line);
                    if (line.Contains("$$$$"))
                    {
                        stcnt++;
                        if ((stcnt % splstrcnt) == 0 && stcnt != 0)
                        {
                            flnmbr++;
                            writer.Close();
                            if (sr.Peek() > -1)//если єто последняя строка то новій файл не создаем
                            {
                                writer = new StreamWriter(@out + "-" + filenumber[flnmbr] + ".sdf");
                                textBox15.AppendText("\r\n" + DateTime.Now.ToString("HH:mm:ss") + "< " + @out + "-" + filenumber[flnmbr] + ".sdf");
                            }
                        }
                    }
                }
                writer.Close(); //закрываем Writer
                textBox15.AppendText("\r\n" + DateTime.Now.ToString("HH:mm:ss") + "< SDF processing finished in: " + timer11 + "\r\nSDF has " + stcnt + " structures\r\n\r\n");
                MessageBox.Show("Splitting finished", "SDF", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
        else { MessageBox.Show("Enter number structures per file", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); textBox14.Focus(); }
    }
    else
    {
        MessageBox.Show("Firstly open SDF file", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}
Добавлено через 9 минут
подскажите пожалуйста еще один момент
мне из строки > <field> надо сделать "field"
C#
1
string.Replace("> <","\"").Replace(">","\"")
не работает, возвращает " <field"
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
21.01.2015, 14:33
Лучший ответ Сообщение было отмечено Psilon как решение

Решение

C#
1
2
            string s = " > <field>";
            string result = s.Trim('>', '<', ' ');
0
1 / 1 / 2
Регистрация: 02.10.2013
Сообщений: 76
21.01.2015, 14:38  [ТС]
а если поле будет: > <field one> то пробел ведь тоже удалит? проверю вечером, сейчас нет VS на ноуте
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
21.01.2015, 14:43
tigorlab, не удалит.
0
1 / 1 / 2
Регистрация: 02.10.2013
Сообщений: 76
21.01.2015, 17:21  [ТС]
Спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.01.2015, 17:21
Помогаю со студенческими работами здесь

Разбивка цикла на несколько потоков
Добрый день! Подскажите каким образом я могу разбить выполнение цикла на 2 потока? Есть у меня 2 таблицы DataTable с полученными...

Разбивка одного столбца на несколько
Добрый день. Проблема состоит в следующем: есть две таблицы Project и Budget связаны по полям Project.Id и Budget.Project. Нужно вывести...

Декомпозиция файла стилей в несколько less-файлов
Добрый день, прошу помощи у знающих. На одном большом проекте было принято решение перевести все стили в Less. Я создал общий файл...

Разбивка таблицы в WORD на несколько документов
Здравствуйте, поставили задачу разбить таблицу, которая создана в WORD (каталог) на отдельные документы *.doc. Объем грандиозный, а...

Скопировать текст из файла в несколько других файлов
Всем привет. Я новичок в Питоне, прошу помощи с такой задачей: Имеется .txt файл с выводом команд маршрутизатора. Он имеет следующий...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru