Что нового

Случайная строка из большого файла

ArgoNaft

Новичок
Сообщения
129
Репутация
0
Мне нужно выбрать из файла случайную строку, считывать в массив весь файл при его объеме 44мб я думаю не сильно верное решение, может есть какие то более гуманные методы работы?


Добавлено:
Сообщение автоматически объединено:

Код:
Func rand_string($file_sorc)
	  $file = FileOpen(@ScriptDir&"\"&$file_sorc, 0)
	  $CountLines = _FileCountLines(@ScriptDir&"\"&$file_sorc)
	  $sLine = FileReadLine($file,Random(1, $CountLines-1, 1))
	  FileClose($file)
	  Return $sLine
EndFunc

решил сам, кому может быть поможет :IL_AutoIt_1:
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
ArgoNaft
Читать весь файл всё равно придётся.
FileRead - прочитать файл
StringReplace - подсчитать количество строк
Random - случайная строка в диапазоне до максимума
FileReadLine - чтение строки

Код:
$sPath = @ScriptDir & '\file.txt'
$sText = FileRead($sPath) ; читает файл
StringReplace($sText, @LF, '') ; подсчёт символов @LF по количеству замен
$iRand = Random(1, @extended-1, 1) ; номер случайно строки
$iPos = StringInStr($sText, @LF, 1, $iRand) + 1 ; поиск LF начала случайной строки
$iPosEnd = StringInStr($sText, @LF, 1, 1, $iPos) ; поиск LF конца
$sRes = StringMid($sText, $iPos, $iPosEnd - $iPos - 1) ; Прочитать строку
MsgBox(0, 'Сообщение', '|' & $sRes & '|')
 
Автор
A

ArgoNaft

Новичок
Сообщения
129
Репутация
0
зачем читать то все? вон я код выложил работает как нужно без чтения
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
ArgoNaft
Посмотри функцию _FileCountLines изнутри. Если уж прочитал, то нет смысла закрывать, можно не отходя от кассы получить строку, в памяти быстрее будет.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Где? Если в конце @LF то следующая строка пустая. Перенос сделан но текста нет.
 
Автор
A

ArgoNaft

Новичок
Сообщения
129
Репутация
0
не понимаю :smile:
Код:
$CountLines-1

у меня стоит специально вот -1
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
ArgoNaft
Не понимаю твоего оправдания? Я претензий не писал. Если ты цитируешь мой пост из другой темы, то надо давать ссылку. В вторых последняя строка должна возвращаться по условию задачи. Я кстати тоже в своём примере не дополнил случаем последней строки. Думаю при 40 Мб строк это не суть важно, я тестировал с файлом 11Мб=153000 вполне достаточно, а если было бы 5 строк, то игнорирование одной строки было бы заметно.
 
Автор
A

ArgoNaft

Новичок
Сообщения
129
Репутация
0
я не кого не цитировал вообще, я просто хотел узнать что не так с последней строкой .... вот и все. Спасибо за помощь
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
ArgoNaft
Ок, не допонял. Ещё больше не понял.

Кстати вот самый простой вариант. Лёгкий в понимании и учитывает все строки.
Код:
$Text = FileRead($sPath)
$Text = StringSplit($Text, @CRLF, 1)
$Text = $Text[Random(1, $Text[0], 1)]
MsgBox(0, 'Сообщение', '|' & $Text & '|')


А то предыдущей ещё не учитывает первую строку.
 
Автор
A

ArgoNaft

Новичок
Сообщения
129
Репутация
0
FileRead не нравиться мне тут, читать файлы такие большие, я вот в том то и дело хотел обойтись без чтения всего файла
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
ArgoNaft
Посмотри функцию _FileCountLines. Ты вставляешь себе в скрипт ещё больший код, включая FileRead. Все функции в UDF написаны нативными функциями в виде включаемых файлов содержащих эти функции.
Код:
Func _FileCountLines($sFilePath)

	Local $hFile = FileOpen($sFilePath, $FO_READ)
	If $hFile = -1 Then Return SetError(1, 0, 0)
	Local $sFileContent = StringStripWS(FileRead($hFile), 2)
	FileClose($hFile)
	Local $aTmp
	If StringInStr($sFileContent, @LF) Then
		$aTmp = StringSplit(StringStripCR($sFileContent), @LF)
	ElseIf StringInStr($sFileContent, @CR) Then
		$aTmp = StringSplit($sFileContent, @CR)
	Else
		If StringLen($sFileContent) Then
			Return 1
		Else
			Return SetError(2, 0, 0)
		EndIf
	EndIf
	Return $aTmp[0]
EndFunc   ;==>_FileCountLines
 
Автор
A

ArgoNaft

Новичок
Сообщения
129
Репутация
0
я и не знал что она такая страшная :smile: внутри
 

WR-e-D

Новичок
Сообщения
53
Репутация
3
Код:
#Include <File.au3>
Global $File = "file.txt"
$one = FileReadLine($File, Random(1, _FileCountLines($File), 1))
ConsoleWrite($one)
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Ещё вариант:

Код:
$sRandom_Line = _FileReadRandomLine(@DesktopDir & '\Test.txt')
MsgBox(64, 'Random line', @extended & '. ' & $sRandom_Line)

Func _FileReadRandomLine($sFile)
	Local $sText, $iLines, $iRandom, $aText
	
	$sText = FileRead($sFile)
	
	If @error Then
		Return SetError(1, 0, '')
	EndIf
	
	StringReplace($sText, @LF, '')
	$iLines = @extended + 1
	
	$iRandom = Random(1, $iLines, 1)
	$aText = StringRegExp($sText, '(?m)(?:[^\r\n]*(?:\r?\n|\z)){' & $iRandom - 1 & '}([^\r\n]*)(?:\r?\n|\z)', 3)
	
	If IsArray($aText) Then
		Return SetExtended($iRandom, $aText[0])
	EndIf
	
	Return SetError(2, 0, '')
EndFunc
 
Верх