Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Работа с большими текстовыми файлами. / 25 сообщений из 168, страница 1 из 7
06.12.2011, 19:38
    #37561725
Alex_men
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
Добрый вечер, уважаемые !

Стоит вот задача разбора и анализа логов. Несмотря на то что файлы логов ежедневно создаются новые размер дневного лога вполне может достигать 200-300 Мб. Из этого объема информации надо вычленить нужную мне и выгрузить в отдельный файл. Логи пишутся сторонней программой. В принципе прослеживается определенная структура в виде заголовков строк.
В чем заковыка. Разработчики дают прогу разбора лога, но без возможности выгрузить информацию. За возможность ткнуть мышкой в нужное событие и выгрузить в отдельный файл информацию просят денежку или сиди делай копипаст.
У них эта прога разбирает файл 55 мб по событиям за 12 секунд. Если я просто пройдусь по этому файлу
Код: plaintext
1.
a.readline

то уже потрачу 24 секунды. а нужно еще и проанализировать и выгрузить. Если я загоняю информацию построчно в mdb на это тратится порядка 4 минут, что уже совсем не айс. А отчеты приходится делать за период до 2-3 лет. Т.е Информации море.

Подскажите может есть более шустрые методы обработки таких объемов текстовой информации? Может можно файл загнать в память и там переварить? Или может кто решал аналогичные задачи?
...
Рейтинг: 0 / 0
06.12.2011, 19:44
    #37561736
Alex_men
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
Alex_men,

Можно конечно считать сразу весь файл
Код: plaintext
1.
a.readall

в память а дальше его как обрабатывать?
...
Рейтинг: 0 / 0
06.12.2011, 19:54
    #37561751
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
пример лога опубликуй

возможно, самый быстрый способ будет - загрузить его в mdb через odbc
...
Рейтинг: 0 / 0
06.12.2011, 20:10
    #37561768
Alex_men
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
Shocker.Pro,
не знаю будет ли это достаточным. Вот кусок описывающий одно событие. Для краткости содержимое секций убрал. В секциях XML описание событий (это описание разбирать не требуется). Нужно выловить из череды событий нужное исходя из содержимого секции UserInfo.

Код: plaintext
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.
[2011.11.28 00:54:45:730][TraceID: TWDPWCC8R36HNU]->IncomingTime

[2011.11.28 00:54:45:730][TraceID: TWDPWCC8R36HNU]->IncomingData

[2011.11.28 00:54:45:730][TraceID: TWDPWCC8R36HNU]->ThreadID

[2011.11.28 00:54:45:730][TraceID: TWDPWCC8R36HNU]->RequestExecuteStart

[2011.11.28 00:54:45:730][TraceID: TWDPWCC8R36HNU]->RequestInfo

[2011.11.28 00:54:45:730][TraceID: TWDPWCC8R36HNU]->CheckUserInfo

[2011.11.28 00:54:45:730][TraceID: TWDPWCC8R36HNU]->UserInfo

[2011.11.28 00:54:45:730][TraceID: TWDPWCC8R36HNU]->TraceParams

[2011.11.28 00:54:45:730][TraceID: TWDPWCC8R36HNU]->StartExecuteTask

[2011.11.28 00:54:45:746][TraceID: TWDPWCC8R36HNU]->EndExecuteTask

[2011.11.28 00:54:45:746][TraceID: TWDPWCC8R36HNU]->RequestExecuteEnd

[2011.11.28 00:54:45:746][TraceID: TWDPWCC8R36HNU]->OutgoingData

[2011.11.28 00:54:45:746][TraceID: TWDPWCC8R36HNU]->OutgoingTime
...
Рейтинг: 0 / 0
06.12.2011, 20:20
    #37561782
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
а-а-а... то есть исходник не текст, XML?
тогда я пожалуй помолчу, ибо опыт маловат
...
Рейтинг: 0 / 0
06.12.2011, 20:36
    #37561807
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
Alex_menДля краткости содержимое секций убрал.Лучше вернуть. Если исходные данные это xml, то при применении xsl 12 секунд на 55 мегов кажутся черепашьей скоростью. Впрочем, я сейчас на шустром железе.
Формат решает всё.
...
Рейтинг: 0 / 0
06.12.2011, 21:20
    #37561869
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
Текстовые логи удобнее разбирать на awk, и по скорости работы его побить невозможно.
Главный учебник здесь: http://www.gnu.org/s/gawk/manual/gawk.html
Виндовых версий море, лучше взять вот эту: http://gnuwin32.sourceforge.net/packages/gawk.htm
...
Рейтинг: 0 / 0
06.12.2011, 22:53
    #37562009
парсер
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
можно приблизительно оценить скорость с какой это можно сделать
скорость современного диска на чтение 30 мбайт\сек
для файла 300 мбайт получается 10 сек
те чтобы загрузить в память весь 300 мбатный файл надо всего лишь 10 секунд
прочитать всю память размером 1гигибайт грубо говоря можно за секунду
так что возможно сделать то что нужно достаточно быстро
к сожалению из формулировки вопроса не понятен формат файла
но алгорим такой
1 выделить 300 мбайт памяти
2 прочитать в нее весь файл
3 можно читать по кусочам и это не замедлит общее время просто мороки больше а 300 мбайт свободных есть на любом нормальном компе на сегодняшний день
4 сканируем побайтно память пока не найдем искомую строку как я понимаю ("UserInfo")
5 парсим дальше как надо


то что a.readline занимаем 24 секунды означает что неверный алгоритм программы
...
Рейтинг: 0 / 0
06.12.2011, 22:55
    #37562014
парсер
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
если алгоритм парсера простой то проше сделать все вручную чем искать и смотреть проги
...
Рейтинг: 0 / 0
07.12.2011, 08:27
    #37562278
Alex_men
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
Shocker.Pro,

Исходник это текст. просто часть секций описывает действия пользователя (доступ и работу с сайтом) в XML, а часть описывает реакцию системы текст. Так что в целом лучше рассматривать как текст.
...
Рейтинг: 0 / 0
07.12.2011, 08:49
    #37562294
Alex_men
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
парсерможно приблизительно оценить скорость с какой это можно сделать
скорость современного диска на чтение 30 мбайт\сек
для файла 300 мбайт получается 10 сек
те чтобы загрузить в память весь 300 мбатный файл надо всего лишь 10 секунд

если дать команду
Код: plaintext
1.
a.ReadAll

то файл в 55 метров загрузится в память за 8 секунд. Возможно у меня машинка не самая мощная, и винты еще IDEшные. но как говорится что имеем.

парсерпрочитать всю память размером 1гигибайт грубо говоря можно за секунду
так что возможно сделать то что нужно достаточно быстро
к сожалению из формулировки вопроса не понятен формат файла
но алгорим такой
1 выделить 300 мбайт памяти
2 прочитать в нее весь файл
3 можно читать по кусочам и это не замедлит общее время просто мороки больше а 300 мбайт свободных есть на любом нормальном компе на сегодняшний день
4 сканируем побайтно память пока не найдем искомую строку как я понимаю ("UserInfo")

в этом направлении сейчас и буду копать. Вся фишка в том что это всего лишь 3-я моя программа на VB, поэтому не все полезности мне известны. Например как прочить файл в память я нашел. А вот что потом в памяти с ним делать пока не знаю :( ни как сканировать ни как выгружать куски загруженного файла.

выгружать мне надо не только секцию ("UserInfo"), а весь Фрагмент лога от "IncomingTime" до "OutgoingTime" который содержит в себе секцию ("UserInfo") с параметром "Иванов Иван Иванович". Так что помимо найти секцию мне надо еще перейти на начало фрагмента IncomingTime и выгрузить весь фрагмент целиком до "OutgoingTime". А затем продолжить поиск


парсер5 парсим дальше как надо


то что a.readline занимаем 24 секунды означает что неверный алгоритм программы

:) я приведу код процедуры, которой я проводил оценку, а вы пожалуйста где косяк :)

Код: plaintext
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.
Private Sub btn_search_Click()
On Error GoTo errlbl
    Dim fso As FileSystemObject
    Dim f As Folder
    Dim a As TextStream
    Dim ist_path, rez_path As String

    Dim f_name As String
    
    Screen.MousePointer = 11
    ist_path = ""
    rez_path = ""
        
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    Set f = fso.GetFolder(ist_path)
       
       f_name = Dir(ist_path & "*.log", vbNormal)
        
       Set a = fso.OpenTextFile(ist_path & f_name, ForReading)

       While Not a.AtEndOfStream
            a.ReadLine
            'rst.AddNew: rst("str_fld") = a.ReadLine
            DoEvents            
        Wend        
        
        a.Close
        Set a = Nothing
    MsgBox "Анализ логов завершен!", vbInformation, ""
    Screen.MousePointer = 0
    
    Exit Sub
    
errlbl:
    Screen.MousePointer = 0
    MsgBox Err.Description, vbCritical + vbOKOnly, Err.Number
End Sub
...
Рейтинг: 0 / 0
07.12.2011, 09:03
    #37562307
Alex_men
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
парсер,

ну собственно алгоритм примерно такой :

-------------> Читаем файл <-----------------------
| | |
| если нашли UserInfo с заданным критерием--нет --
| |
| да
| |
| выгружаем фрагмент в файл результат
| |
-----нет--- если читаемый файл EOF
^ |
| да
| |
| есть ли еще файлы-------------нет----------
| | |
| да конец программы
| |
-------- переходим к следующему файлу
...
Рейтинг: 0 / 0
07.12.2011, 09:08
    #37562310
Alex_men
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
Извиняюсь забыл про пробелы
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
    ------------->  Читаем файл <-----------------------
   |                               |                                         |
   |    если нашли UserInfo с заданным критерием--нет --
   |                               |
   |                              да
   |                               |
   |       выгружаем фрагмент в файл результат
   |                               |
   -----нет--- если читаемый файл EOF
   ^                               |
   |                               да
   |                                |
   |                   есть ли еще файлы-------------нет----------
   |                                |                                                 |
   |                               да                                    конец программы
   |                                |
   -------- переходим к следующему файлу
...
Рейтинг: 0 / 0
07.12.2011, 10:32
    #37562445
novexelf
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
Alex_men,

Неужели скорость так важна? может зря бьетесь за этот параметр?

Уже несколько лет сопровождаю ПО которое загружает кучу логов, отчетов, данных из других БД, и на все это требуется до 3-х дней, а после еще полдня на генерацию нужных отчетов, но пользователям этот цикл нужно повторять один раз в месяц, поэтому даже 4-5 дней для них не проблема, хотя от некоторых и слышу - загрузка таких-то данных длилась 8 часов, можли ли ускорить, такое впечатление, что они уголь 8 часов грузили, поэтому когда спрашиваю для чего, то ни кто из них объяснить не может, по факту - запустили и забыли.
...
Рейтинг: 0 / 0
07.12.2011, 11:02
    #37562519
Alex_men
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
novexelf,

К сожалению важно. Информация по логам предоставляется 5-10 раз в месяц за различный период (до 5 лет, а это примерно 10 гиг текста в год и больше). пока запрос доходит до меня из-за бюрократии теряется от 4 часов до суток, а на подготовку дается 3 дня с момента отправки запроса. при этом возможно одновременное поступление нескольких запросов. Вот недавно пришел запрос информации за 3 года. разбору подлежало 34 гига текста. Та программка что у меня была давно на akse разбирала это около 2 и 1/2 -суток на очень хорошей рабочей станции. Хочу сократить время хотябы раза в 3 время на разбор и при этом чтобы работало на средней по мощности рабочей станции, тем более что анализатор разработчиков дразнит скоростью капитально.
Как я уже говорил за 12 секунд он считывает файл в 55 МБ и разбирает его по деталям. Можно смотреть информацию в разрезе пользователя, или в разрезе сессии, или по времени событий... Только выгрузки не дает и потоковости обработки. Моя же нынешняя прога будет возится с тем же файлом по указанному алгоритму примерно 4-5 минут. Разница очевидна
...
Рейтинг: 0 / 0
07.12.2011, 11:08
    #37562534
Alex_men
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
Alex_men,

есть еще одна заковыка. не знаю из каких соображений но у разработчиков в логах встречаются строки по 67-70 тыс символов. Тут уже и мемо поля не помогут рубить будет :(
...
Рейтинг: 0 / 0
07.12.2011, 11:28
    #37562587
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
Если речь идет о VB, а не о VBS, то FileSystemObject не нужен.
VB умеет сам работать с файлами.
Open/Get/Input/Close.
...
Рейтинг: 0 / 0
07.12.2011, 11:46
    #37562634
novexelf
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
Alex_men,

Насколько я понял, у вас файл xml, некоторой структуры, так почему бы не подвязать его к акссесу? это будет явно быстрее, чем парсить самостоятельно, ну и после можно будет запрос выполнить ...
...
Рейтинг: 0 / 0
07.12.2011, 12:08
    #37562693
Alex_men
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
novexelf,

XML не во всех секциях и мне его разбирать не надо мне его надо выгрузить вот например секция :

[2011.11.28 00:54:45:730][TraceID: TWDPWCC8R36HNU]->IncomingData\706
FЪКД2 TWDPWCC8R36HNU P Connection: Keep-Alive
Accept: text/html, application/xhtml+xml, */*
Accept-Encoding: gzip, deflate
Accept-Language: ru-RU
Cookie: exp_path=C%3A%5CUsers%5C%u0412%u0430%u0434%u0438%u043C%5CDesktop; __utma=179010226.226380545.1311577166.1321904062.1322427283.33; __utmz=179010226.1311577166.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmb=179010226.1.10.1322427283; SID=6a58efcbb44bba88asdb9bb087; hotlog=1; __utmc=179010226
Host: www.тра-та-та.ru
Referer: http://www.тра-та-та.ru/
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; BOIE9;RURU)
T=R_Loader.Load7 # RequestInfo=12.16.1.5|12.16.1.9 ccSITE=R
...
Рейтинг: 0 / 0
07.12.2011, 15:49
    #37563308
парсер
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
Код: vbnet
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.
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.
Attribute VB_Name = "FileParseM"
Option Explicit


Public Sub Test02()
    Dim strFilePath As String
    Dim dtmBegin As Date
    Dim dtmEnd As Date
    Dim dtmDifference As Date


    dtmBegin = Now

    strFilePath = "c:\log.txt"
    FileParse strFilePath

    dtmEnd = Now
    dtmDifference = dtmEnd - dtmBegin
    MsgBox "time " & Format(dtmDifference, "ss")
End Sub

Private Sub FileParse(ByVal strFilePath As String)
    Dim strBuffer As String


    FileRead strFilePath, strBuffer
    BufferParse strBuffer
End Sub

Private Sub FileRead(ByVal strFilePath As String, ByRef strBuffer As String)
    Dim lngFileLength As Long
    Dim lngFileHandle As Long


    lngFileHandle = FreeFile()
    Open strFilePath For Binary Access Read Write Shared As lngFileHandle

    lngFileLength = LOF(lngFileHandle)
    strBuffer = String(lngFileLength, 0)

    Get lngFileHandle, , strBuffer
    Close lngFileHandle
End Sub

Private Sub BufferParse(ByRef strBuffer As String)
    Dim lngUserInfoPosition As Long
    Dim lngLineBeginPosition As Long
    Dim lngLineEndPosition As Long
    Dim lngCurrentPosition As Long
    Dim strUserInfo As String
    Dim strLineBegin As String
    Dim strLineEnd As String
    Dim strFound As String


    strUserInfo = "UserInfo"
    strLineBegin = vbCrLf
    strLineEnd = vbCrLf

    lngCurrentPosition = 1
    Do While lngCurrentPosition <= Len(strBuffer)
        ' userinfo string
        lngUserInfoPosition = InStr(lngCurrentPosition, strBuffer, strUserInfo, VbCompareMethod.vbTextCompare)
        If lngUserInfoPosition = 0 Then
            Exit Do
        End If

        ' line begin
        lngLineBeginPosition = InStrRev(strBuffer, strLineBegin, lngUserInfoPosition, VbCompareMethod.vbTextCompare)
        If lngLineBeginPosition = 0 Then
            Exit Do
        End If

        ' line end
        lngLineEndPosition = InStr(lngUserInfoPosition, strBuffer, strLineEnd, VbCompareMethod.vbTextCompare)
        If lngLineEndPosition = 0 Then
            Exit Do
        End If
        
        strFound = Mid(strBuffer, lngLineBeginPosition + Len(strLineBegin), lngLineEndPosition - lngLineBeginPosition - Len(strLineBegin))
        MsgBox strFound

        lngCurrentPosition = lngLineEndPosition + Len(strLineEnd)
    Loop
End Sub



я предположил что конец и начало строки это границы на которых надо извлечь данные

только если будет очень много записей (100 000) то понятно что экспорт их даже с текст файл затормозит прогу а простое сканирование выполняется быстро
...
Рейтинг: 0 / 0
07.12.2011, 15:54
    #37563328
парсер
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
по поводу btn_search_Click
1 тормозит вызов readLine тк при каждом вызове выделяется память для возвращаемой строки когда строк 1 000 000 это очень тормозит поэтому память надо выделять только один раз эта главная причина
2 тормозит DoEvents насколько томозит не знаю можно замер сделать
...
Рейтинг: 0 / 0
07.12.2011, 16:30
    #37563428
Alex_men
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
парсер,

Строк в файле на 55 Мб получается порядка 850 тыс. Занялся изучением вопроса управления выделяемой памятью.
Спасибо за код сел разбираться.
по поводу
Код: vbnet
1.
DoEvents

я уже нашел и промерил. для того же выше указанного цикла с простым ReadLine, если DoEvents делать не каждый раз (я сделал раз в 100 циклов) время сократилось с 24 сек до 8. Дальнейшее увеличение количества циклов, когда DoEvents не отрабатывает, на скорость не повлияло, а вот попасть по кнопке "стоп" становится проблемно. Спасибо

Вам за помощь. Ничего если будут вопросы еще поуточняю кое чего? :)
...
Рейтинг: 0 / 0
07.12.2011, 16:59
    #37563509
парсер
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
спрашивайте
я думаю можно просто запустить Test02 для лог файла и посмотреть что получится
...
Рейтинг: 0 / 0
07.12.2011, 17:13
    #37563539
Alex_men
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
парсер,

Просто запустить это я конечно сделаю. Но мне важно еще и самому разобраться и понять что и как там внутри тикает.
...
Рейтинг: 0 / 0
07.12.2011, 17:27
    #37563570
Alex_men
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с большими текстовыми файлами.
парсер,

Кстати сходу не распознает
Код: vbnet
1.
Attribute VB_Name = "FileParseM"



У меня VB6. Если в MSDN пока нашел описание для VB.NET
...
Рейтинг: 0 / 0
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Работа с большими текстовыми файлами. / 25 сообщений из 168, страница 1 из 7
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]