Busqueda en un archivo TXT y no morir en el intento.

157 views
Skip to first unread message

Dsan

unread,
Apr 12, 2022, 12:04:37 PM4/12/22
to publice...@googlegroups.com
Hola buenos días a todos.

Me surgió algo, 
Me pasaron un archivo.txt con 10 millones de registro es una sola columna, en el cual tengo que ir a buscar cierta cantidad de registros que están en una tabla de excel, esto último no es problema, sino buscar la cadena de una manera exacta y rápida; alguna recomendación?

gracias de antemano.

Dsanchez

Marco Plaza

unread,
Apr 12, 2022, 2:29:50 PM4/12/22
to Comunidad de Visual Foxpro en Español
Hola Daniel, chequea este código que compartí hace algún tiempo en " Searching large text files | Foxite "
( 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)


```

Zen Tes

unread,
Apr 13, 2022, 12:28:17 PM4/13/22
to Comunidad de Visual Foxpro en Español
Excelente trabajo Marco. Ubica en 3 segundos un texto en un archivo de texto de 1.18 GB.
Prueba realizada en un Computador Ryzen 5 de 16 RAM. Disco Solido.
Saludos.

Esteban Herrero

unread,
Apr 13, 2022, 4:15:47 PM4/13/22
to publice...@googlegroups.com

Muy bueno Marco...

Lo probé y realmente es muuuy rápido.

Una busqueda en un TXT de 205Mb en 0.169... Impresionante...

Saludos

--
Blog de la Comunidad Visual FoxPro en Español: http://comunidadvfp.blogspot.com
---
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/publicesvfoxpro/3da4c99d-34de-4857-a4dd-d6b32ed5887fn%40googlegroups.com.

Dsan

unread,
Apr 15, 2022, 12:58:24 PM4/15/22
to publice...@googlegroups.com
Muchas gracias Marco Plaza, ya pruebo

Saludos

Douglas





Marco Plaza

unread,
Apr 16, 2022, 10:51:42 AM4/16/22
to Comunidad de Visual Foxpro en Español
siempre alguna vez se necesita algo así.. y bueno ahí está.

( lo más interesante fue comprobar como vfp utiliza la memoria; 
si colocan un "chunk" muy grande el rendimiento va bajando! )

Saludos.

Reply all
Reply to author
Forward
0 new messages