Что нового

[Данные, строки] Обработка файлов большого размера

ahjkcfout7

Знающий
Сообщения
26
Репутация
6
Доброго времени суток. Имеется файл логов брандмауэра в котором около 1млн строк. Из файла необходимо получить ряд айпи адресов и портов. При выполнение кода, программа обрабатывает первые 10000 строк примерно за минуту, однако последующая 10я тысяча увеличивает время обработки и тд. Каким образом уменьшить время обработки файла? Я привожу код программы и часть файла логов https://www.sendspace.com/file/k9vapc
Код:
#include <File.au3>
#include <array.au3>
#include <String.au3>
#include <File.au3>
$sFilePath="c:\netlog.log"
Dim $arr[1]
Dim $arr1[1]
$file=FileOpen($sFilePath,0)
$file_ans=FileOpen("c:\ans.txt",1)
;~_FileReadToArray($sFilePath, $arr1)
;~ _ArrayDisplay($arr1)
;~ $serchstring=
$finish=_FileCountLines($sFilePath)
ConsoleWrite($finish&@CR)
$i=0
;~ Dim $sercharr=[":6881",":6883",":6881","224.0.0.252:5355","239.255.255.250:1900","239.255.255.250:1900","192.168.1.1:7"]
;~ For $i=1 To $finish
   While True
	  $i+=1
 ;~  ConsoleWrite($i&@CR)
   $workstring=FileReadLine($file,$i)
   If Not StringInStr($workstring,"new packet connection: UDP/192.168.1.50:")=0 Then
	  If StringInStr($workstring,"239.255.255.250:1900")=0 Then
		 If StringInStr($workstring,"192.168.1.1:7")=0 Then
			If StringInStr($workstring,"224.0.0.252:5355")=0 Then
			   If StringInStr($workstring,":6881")=0 And StringInStr($workstring,":6882")=0 And StringInStr($workstring,":6883")=0 Then
				  $workstring=_StringBetween($workstring, 'new packet connection: UDP/', '<n/a:0>')
				  $workstring=_ArrayToString($workstring)
				  FileWriteLine($file_ans,$workstring)
			   EndIf
			EndIf
		 EndIf
	  EndIf
	EndIf
;~ Next
WEnd
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
247
Почему отказались от варианта работы с массивом ? Ведь в разы быстрее !
Код:
#include <File.au3>
#include <array.au3>
#include <String.au3>
#include <File.au3>
$sFilePath=@ScriptDir&"\netlog.log"
Dim $arr[1]
Dim $arr1[1]
$file=FileOpen($sFilePath,0)

_FileReadToArray($sFilePath, $arr1)
FileClose($file)
 ;~ _ArrayDisplay($arr1)
;~ $serchstring=
$finish=Ubound($arr1)-1
ConsoleWrite($finish&@CR)
;~ Dim $sercharr=[":6881",":6883",":6881","224.0.0.252:5355","239.255.255.250:1900","239.255.255.250:1900","192.168.1.1:7"]
$n=0
For $i=1 To $finish

  ;~ConsoleWrite($i&@CR)
   $workstring=$arr1[$i]
   If Not StringInStr($workstring,"new packet connection: UDP/192.168.1.50:")=0 Then
      If StringInStr($workstring,"239.255.255.250:1900")=0 Then
         If StringInStr($workstring,"192.168.1.1:7")=0 Then
            If StringInStr($workstring,"224.0.0.252:5355")=0 Then
               If StringInStr($workstring,":6881")=0 And StringInStr($workstring,":6882")=0 And StringInStr($workstring,":6883")=0 Then
                  $workstring=_StringBetween($workstring, 'new packet connection: UDP/', '<n/a:0>')
                  $workstring=_ArrayToString($workstring)
                  Redim $arr[$n+1]
				  $arr[$n]=$workstring
				  $n+=1
               EndIf
            EndIf
         EndIf
      EndIf
    EndIf
 Next
$file_ans=FileOpen(@ScriptDir&"\ans.txt",1)
_FileWriteFromArray($file_ans,$arr)
FileClose($file_ans)
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
ra4o совершенно прав.
Обращение к диску очень долгая операция. Вы, ahjkcfout7, читаете с диска каждую строку файла в отдельности. Прочитав весь файл сразу, Вы значительно ускорите работу своего скрипта.

Ну, моё решение, конечно же, в выборе другого пути
Код:
#include <File.au3>

$subpattern = "(\:6881)|(\:6882)|(\:6883)|(224\.0\.0\.252\:5355)|(239\.255\.255\.250\:1900)|(239\.255\.255\.250\:1900)|(192\.168\.1\.1\:7)"
$pattern = "(?m)^.*?new packet connection\: UDP\/(192\.168\.1\.50(?(?=("&$subpattern&"))(*F)|.)*?)<n/a:0>"

$inText = FileRead("netlog.log")

$aRes = StringRegExp($inText, $pattern, 3)

_FileWriteFromArray("outlog.log", $aRes)
 
Автор
A

ahjkcfout7

Знающий
Сообщения
26
Репутация
6
Cогласен с вами, массивом быстрее. Однако я где-то читал на форуме что количество строк в массиве ограничено 65524. Как быть тогда?
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
ahjkcfout7 [?]
Cогласен с вами, массивом быстрее. Однако я где-то читал на форуме что количество строк в массиве ограничено 65524. Как быть тогда?
Нет, ограничение больше, несколько миллионов
 
Автор
A

ahjkcfout7

Знающий
Сообщения
26
Репутация
6
да..только что проверил; я опирался на функцию arraydisplay. Это только она режит количество элементов. Всем спасибо.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
16 миллионов. вернее 2^24.
Кстати, на длинну строки тоже ограничение в 21 гиг. Так что с регуляркой тоже может не подойти. :(
 
Верх