( permite buscar en TXT de cualquier tamaño )
"La mejor manera que encontré es leyendo en secciones. Usé un archivo de prueba de 218Mb.
La rutina puede realizar una búsqueda de texto en 0,8 segundos si desactivo el Número de línea de retorno,
y 3,4 segundos calculando el número de línea de resultado.
Puedes mejorar aún más el rendimiento usando ParallelFox, ya que este tipo de rutinas
es un buen candidato para ello. Supongo que puede funcionar en paralelo hasta 4 veces más rápido,
dependiendo de tu CPU y memoria, por lo que una búsqueda completamente optimizada en paralelo podría mostrar
da como resultado 0,2 - 0,8 segundos para un archivo de 500 MB.
Puedes probar ajustando el tamaño del fragmento para ver lo que funciona mejor en tus datos/máquina."
```
*--------------------------------------------------------------------
* Marco Plaza, 2016
* @nfoxdev
*--------------------------------------------------------------------
Parameters cFileName,cSearchFor,lLineNumberRequired,LINEDELIMITER,nChunkSize
#Define crlf Chr(13)+Chr(10)
nHandle = Fopen(m.cFileName)
If m.nHandle < 0
Error ' Unable to open file ' + m.cFileName
Return
Endif
******** settings:******************************************
nChunkSize = Evl(m.nChunkSize,500000)
LINEDELIMITER = Evl(m.LINEDELIMITER,Chr(10)) && must be 1 character!
cOut = Forceext( m.cFileName,'.search.txt')
***********************************************************
Erase (m.cOut)
StartSecond = Seconds()
biteNextLine = 0
nlinesRead = 0
nFileLine = 0
Do While .T.
cTxt = Fread( m.nHandle , m.nChunkSize )
nBytesRead = Len(m.cTxt)
If m.nBytesRead = 0
Exit
Endif
If lLineNumberRequired
nlinesRead = m.nlinesRead + Occurs(m.LINEDELIMITER,m.cTxt)
Endif
Do While .T.
nPosFound = At(m.cSearchFor,m.cTxt)
If nPosFound = 0
Exit
Endif
lineStartPos = Rat(m.LINEDELIMITER,Left(m.cTxt,m.nPosFound))+1
rightDelimPos = At(m.LINEDELIMITER,Substr(m.cTxt,m.nPosFound+1))
If m.rightDelimPos > 0
lineLength = ( m.nPosFound - m.lineStartPos ) + m.rightDelimPos - 1
LineContent = Substr( m.cTxt, m.lineStartPos , m.lineLength )
nNextLineStart = m.lineStartPos+m.lineLength + 1
cTxt = Substr(m.cTxt,m.nNextLineStart)
Else
thisLine = Substr( m.cTxt, m.lineStartPos )
nextChunk = Fread( m.nHandle , m.nChunkSize )
posDelim = At(m.LINEDELIMITER,m.nextChunk)
npDelim = Evl(m.posDelim,Len(m.nextChunk))
m.lineContent = m.thisLine + Left(m.nextChunk,m.npDelim-1)
nlinesRead = m.nlinesRead+1
cTxt = Substr( m.nextChunk, m.npDelim+1)
Endif
If lLineNumberRequired
nFileLine = m.nlinesRead-Occurs(m.LINEDELIMITER,m.cTxt)
Endif
Strtofile( Transform(m.nFileLine)+':'+m.lineContent+crlf, m.cOut,1)
Enddo
Enddo
Fclose(m.nHandle)
Strtofile( 'total time: '+Transform(Seconds()-m.StartSecond),m.cOut,1)
Modify File (m.cOut)
```