1 de noviembre de 2020

Cargar un número grande de archivos mediante ADIR()

La función ADIR() es una manera práctica de cargar todos los archivos (o de un subconjunto de todos los archivos) de una carpeta específica, en un Array. En la mayoría de los usos típicos de ADIR(), el número de archivos y por lo tanto el tamaño del Array, no es una cuestión a discutir.

Sin embargo, en aquellos escenarios donde el número de archivos que Ud. desea cargar es muy grande (mas de 10.000), existen estos problemas:

1) En versiones de VFP anteriores a VFP 9.0, ADIR() estaba limitado a cerca de 12.800 filas, debido al límite de 64.000 items máximos de un Array. Si la carpeta específicada contiene mas de 12.800 archivos, ADIR() genera un error.

2) VFP 9.0 elimina la limitación de 64.000 items, pero cuando usted intenta cargar y después procesar las filas del Array, el rendimiento sufre porque el Array entero se carga en memoria.

El siguiente código muestra una manera de solventar el problema usando la función SYS(2000) que carga un archivo a la vez en un cursor y a) Trabaja en cualquier versión de VFP y b) Consume muy poca memoria, porque solamente una fila del Array a la vez, se almacena en memoria.

CLEAR 
LOCAL xx
*
*  create 12,000 files with the ".TST" extension,
*  the limit when using VFP 8.0 or lower -- feel
*  free to increase this number dramatically in 
*  VFP 9 and higher
*
FOR xx = 1 TO 12000
  STRTOFILE("File " + TRANSFORM(m.xx),"File"+TRANSFORM(m.xx)+".TST",0)
ENDFOR
*
*  try it the ADIR() way
*
start = SECONDS()
CREATE CURSOR FileList (FileName C(60), ;
                        FileSize I, ;
                        LastModD D, ;
                        LastModT C(8), ;
                        FileAttr C(10))
LOCAL laDir[1]
ADIR(laDir,"*.TST")
INSERT INTO FileList FROM ARRAY laDir
end = SECONDS()
? end-start, RECCOUNT("FileList")
USE IN FileList
*
*  try it the SYS(2000) way
*
start = SECONDS()
CREATE CURSOR FileList (FileName C(60), ;
                        FileSize I, ;
                        LastModD D, ;
                        LastModT C(8), ;
                        FileAttr C(10))
LOCAL lcFile
lcFile = SYS(2000,"*.TST")
DO WHILE NOT EMPTY(m.lcFile)
    ADIR(laFile, m.lcFile)
    INSERT INTO FileList FROM ARRAY laFile
    lcFile = SYS(2000,"*.TST",1)
ENDDO
end = SECONDS()
? end-start, RECCOUNT("FileList")
USE IN FileList
ERASE *.TST
RETURN

VFP Tips & Tricks - Drew Speedie

No hay comentarios. :

Publicar un comentario

Los comentarios son moderados, por lo que pueden demorar varias horas para su publicación.