Нужно оптимизировать работу с большим текстовым файлом

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
DGreen
Начинающий
Начинающий
 
Сообщения: 5
Зарегистрирован: 31.10.2011 (Пн) 21:58

Нужно оптимизировать работу с большим текстовым файлом

Сообщение DGreen » 31.10.2011 (Пн) 22:47

Приветствую всех, возникла проблема, надеюсь кто нибудь сможет мне помочь, самому уже ничего в голову не идет...
Рассказываю :

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

Есть текстовый фаил(Прикрепил, открывать лучше вордом чтобы видеть форматирование текста ) в котором содержатся группы чисел (Групп около 6500 по 37 чисел в каждой, то есть около 250000 символов :shock: ) , задача программы находить в этих группах заданную в поиске последовательность чисел в пределах группы и выдавать число идущее за ними. К примеру мы ищем "30 36 14" программа находит его в группе 1
1, 3 12 20 22 1 18 30 36 14 25 23 28 4 31 33 29 10 35 13 2 17 32 7 21 19 27 26 9 24 15 8 16 5 0 34 11 6
и должна выдать число идущее за ней, то есть 25.

Ну как новичку мне не пришло в голову ничего лучше чем загрузить текстовый фаил в RichText(Именно в него, для того что бы можно было находить символ перехода на новую строку(В Textbox он почему то теряется) , который по сути является началом новой группы) и далее циклом посимвольно вытаскивать с него группы и записывать их в String массив на 10000 ячеек(С запасом потому что групп может быть и больше 6500) . Далее уже проводить поиск непосредственно в массиве и заносить удовлетворяющее результатам поиска в Listbox (Совпадений скорее всего будет множество и все нужно отобразить одновременно).Написал вот такой код (Здесь только часть отвечающая за занесения инфы в массив)
Код: Выделить всё
Dim sek As Long
sek = 0
Dim lens As Long
Dim rew As Long
lens = Len(RichTextBox1.Text)
ProgressBar1.Max = lens
Dim midi As String
For rew = 1 To lens
midi = Mid(RichTextBox1.Text, rew, 1)
If midi = Chr(10) Then
sek = sek + 1
Else

    Mass(sek) = Mass(sek) + midi
   
End If
ProgressBar1 = rew
Next



Ну и в общем работает, но тормозит просто жутко ! Одно занесение инфы в массив занимает наверно около получаса а может и час(не хватало терпения дождаться).

Собственно сам вопрос, можно ли как то отпимизировать это дело что бы оно работало быстрее !? Возможно можно как то избавиться от цикла, или у кого то возникнут идеи как выделить из текста группы не прибегая к посимвольному перебору циклом... Использую 6й VisualBasic .

Заранее спасибо.
Вложения
Фаил.zip
(214.73 Кб) Скачиваний: 62

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Нужно оптимизировать работу с большим текстовым файлом

Сообщение FireFenix » 01.11.2011 (Вт) 2:13

Открыть как бинарный файл, и напрямую делать бинарный посик в цикле, пока не будет удовлетворять условию, а не грузить во всевозможные контролы и через них работать
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

DGreen
Начинающий
Начинающий
 
Сообщения: 5
Зарегистрирован: 31.10.2011 (Пн) 21:58

Re: Нужно оптимизировать работу с большим текстовым файлом

Сообщение DGreen » 01.11.2011 (Вт) 9:33

FireFenix писал(а):Открыть как бинарный файл, и напрямую делать бинарный посик в цикле, пока не будет удовлетворять условию, а не грузить во всевозможные контролы и через них работать


А можно немного поподробнее, а как мне выделить группы из фаила ? Разве в бинарном варианте что то изменится ? Опять тот же цикл выходит ... или в бинарном обработка будет быстрее ?

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Нужно оптимизировать работу с большим текстовым файлом

Сообщение FireFenix » 01.11.2011 (Вт) 12:26

DGreen писал(а):А можно немного поподробнее, а как мне выделить группы из фаила ?

1) Открыть файл For Binary
2) Командой Get выбираешь в массив от начала [1 + размер искомой группы (30 36 14 = 3)]

3)Если данные хранятся в бинарном виде - сравниваешь с эталоном
Если данные в ASCII - сравниваешь с эквивалентом значений ASCII или приводишь к этому виду
Если в других форматах или кодировках - приводишь к нужному виду и сравниваешь

4) Если маска[в данном случае первые 3 байта] равна, то 4ый байт - есть искомый
Если не равны, то увеличиваем смещение на 1 и повторяем пункт 2

DGreen писал(а):Разве в бинарном варианте что то изменится ? Опять тот же цикл выходит ... или в бинарном обработка будет быстрее ?

В данном случае ты напрямую обращаешься к данным в файле, предварительно сохранив их в переменных.

Если ты используешь загрузку в какой-то контрол, то там происходит копирования всего файла в память и его обработка, что в данном случае не нужно и тратиться много времени
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 01.11.2011 (Вт) 13:24

FireFenix, что-то мы по-разному условия понимаем...

DGreen, открыть файл как текстовый, читать построчно и искать (без загрузки в какие-либо контролы).

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Нужно оптимизировать работу с большим текстовым файлом

Сообщение ger_kar » 01.11.2011 (Вт) 16:46

Я думаю можно сделать так, сначала открываем файл и вычисляем его размер и определив согласно его размера буфер считываем файл туда.
А дальше разделяем его на группы и получаем массив этих групп функцией Split по разделителю vbLf.
Как вариант можно считывать в массив построчно.
Дальше каждый элемент массива, то бишь каждую строку-группу разделяем опять при помощи Split но уже по разделителю " " (пробел) во временный массив и уже перебирая этот массив ищем искомое.
Советую посмотреть пример Qwertiy, и прочитать эту тему.
Бороться и искать, найти и перепрятать

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Нужно оптимизировать работу с большим текстовым файлом

Сообщение iGrok » 01.11.2011 (Вт) 17:03

Зависит от того, разовое это действие, или нужно искать в файле несколько разных групп.

Если разовое, то вариант Qwertiy с построчным чтением и поиском лично мне кажется более разумным.

Если файл один и в нём нужно искать подряд несколько разных групп значений, то разумнее один раз распарсить файл в многомерный массив, или похожую структуру, и потом просто выбирать нужные значения примерно так: out = val_arr(in1, in2, in3). Если значений более, чем одно, можно добавить четвёртое измерение.
label:
cli
jmp label

DGreen
Начинающий
Начинающий
 
Сообщения: 5
Зарегистрирован: 31.10.2011 (Пн) 21:58

Re: Нужно оптимизировать работу с большим текстовым файлом

Сообщение DGreen » 01.11.2011 (Вт) 17:35

Большое спасибо всем, работа с бинарным открытием фаила для меня пока сложновата, а вот читать фаил построчно и писать в массив прямо строки действительно хорошая идея, а для поиска по массиву воспользуюсь Instr. Даже на числа группы не придется разбивать, пусть ищет текст себе , а что бы при поиске допустим 3 34 9 избежать попадания в результаты группы с числами 33 34 91 просто добавлю к 3 34 9 пробелы в начала и в конце. Буду пробовать, потом отпишусь о результатах.

DGreen
Начинающий
Начинающий
 
Сообщения: 5
Зарегистрирован: 31.10.2011 (Пн) 21:58

Re: Нужно оптимизировать работу с большим текстовым файлом

Сообщение DGreen » 01.11.2011 (Вт) 19:40

Такс ... и тут же возникла проблема, почему то line input находит в фаиле всего одну строку, то есть он считает все содержимое файла одной строкой, при этом если я для проверки заношу текст в Reachtext, он помещает в него текст из фаила также одной строкой, НО в риче текст уже с переносами строк, то есть сами символы переноса в тексте как бы присутствуют но получается line input не воспринимает их как символы переноса строки... В чем может быть проблема ?

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Нужно оптимизировать работу с большим текстовым файлом

Сообщение ger_kar » 01.11.2011 (Вт) 19:57

Ну вообще посмотрев файл в бинарном редакторе я там обнаружил только символ переноса строки т.е. символ с кодом &H0A или эквивалентный константе vbLf, символ возврата каретки отсутствует. Может Line Input реагирует только на vbCrLf.
В принципе можно сделать массив так MyArray()=Split(strBuffer, vbLf)
Бороться и искать, найти и перепрятать

DGreen
Начинающий
Начинающий
 
Сообщения: 5
Зарегистрирован: 31.10.2011 (Пн) 21:58

Re: Нужно оптимизировать работу с большим текстовым файлом

Сообщение DGreen » 01.11.2011 (Вт) 20:35

ger_kar писал(а):В принципе можно сделать массив так



Получилось !!! Большое спасибо !


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex-бот и гости: 6

    TopList  
cron