'' Cómo eliminar los .TMP temporales

Por Marzo Varea




Ciertamente, no vivimos en el mejor de los mundos imaginables. A veces ocurren accidentes (un error de programación, un fallo de corriente, un RESET imprevisto...), y nuestras (creíamos) bien pensadas aplicaciones no terminan su ejecución del modo regular. En tal caso, quedarán por ahí colgados diversos ficheros temporales, que, además de no hacer bonito precisamente, ocupan sitio, tal vez escaso y siempre aprovechable de mejor manera. Por tanto, puede ser útil una función que nos los borre al arrancar la aplicación; la llamaremos, por ejemplo, BORRATMP.

Los ficheros temporales de FoxPro tienen un nombre de 8 dígitos y la extensión .TMP. Puede haber también ficheros índice temporales (por ejemplo, de un CURSOR), con las correspondientes extensiones .CDX e .IDX. Los ficheros temporales creados "manualmente" y nombrados con la función sys(3) pueden tener la extensión que el programador quiera.

El directorio en que estén dependerá de varias cosas. Si en el Config.FP (o .FPW) hay orden TMPFILES = Loquesea, se encontrarán en ese directorio. Si no, bajo Windows, se encontrarán en el directorio definido por la orden SET TMP del DOS (en el Autoexec.bat); de cualquier modo, la función SYS(2023) nos lo localizará.

En DOS, en cambio, si no hay TMPFILES, los ficheros temporales estarán en el que era el directorio actual (CURDIR()) cuando se crearon; pero SYS(2023) nos devolverá un engañoso "C:".

No he probado en un Mac, de modo que no sé si habrá comportamientos excéntricos, como en DOS. En cualquier plataforma, los ficheros temporales "manuales" pueden crearse en cualquier parte que desee el programador.

Para no prejuzgar, BorraTMP actúa en el directorio que se le pase como argumento, o en el actual si no se le pasa ninguno. Se crea una lista de ficheros con las extensiones .TMP, .CDX e .IDX, en el array Lista, precisamente, gracias a la UDF ADirAd (Ad de Aditivo: permite ir añadiendo a un array existente el resultado de un ADIR, sin machacarlo, a diferencia del ADIR de Fox).

Una vez encontrados habrá que:

  • 1º) contar sólo con aquéllos cuyo nombre sea puramente numérico (para eso usamos la función de usuario EsCadNum, que nos devuelve .T. si su argumento es una cadena de caracteres que represente válidamente un número; aunque, en realidad, para este uso bastaría una más sencilla, tenía ésta ya escrita, y mejorada desde su última publicación, de modo que aprovecho para meterla); y,

  • 2º) ya que estamos dentro de Fox, distinguir los ficheros temporales remanentes de una salida en falso anterior de los creados por la presente sesión. Nada más fácil: los ficheros temporales actuales estarán en uso y abiertos en exclusiva, de modo que no se podrán abrir otra vez: al intentarlo, la función FOPEN() nos devolverá -1. Si no ocurre eso, se trata de un fichero fósil; lo cerramos con FCLOSE(), lo borramos con DELETE FILE, y a por el siguiente de la lista.

    Finalmente, BorraTMP devuelve el número de ficheros que ha eliminado.

    
    ********************************************
    *                    BORRATMP
    *		(C) Marzo Varea Sanz 
    *
    ********************************************
    *	Borra, en el subdirectorio que se le 
    *       indique,
    *	los ficheros .TMP, .CDX e .IDX cuyos 
    *       nombres
    *	consten exclusivamente de cifras 
    *	y que no estén abiertos.
    *
    *	Devuelve el nº de ficheros borrados.
    *
    ********************************************
    
    parameter subdir
    
    private n_borrados
    n_borrados=0
    
    if empty(m.subdir)
    	subdir=""
    else
    	if not right(m.subdir,1)="\"
    		subdir=m.subdir+"\"
    	endif
    endif
    
    private lista,n,i,h
    dimension lista[1]
    =adirad(@lista,m.subdir+"*.tmp")
    =adirad(@lista,m.subdir+"*.cdx")
    n=adirad(@lista,m.subdir+"*.idx")
    
    for i=1 to m.n
    	if EsCadNum(left(lista[m.i,1], ;
    			at(".",lista[m.i,1])-1))
    		h=fopen(m.subdir+lista[m.i,1],2)
    		if m.h#-1
    			=fclose(m.h)
    			delete file (m.subdir+lista[m.i,1])
    			n_borrados=n_borrados+1
    		endif
    	endif
    endfor
    
    return n_borrados
    
    ********************************************	
    *           Func. ADIRAD
    ********************************************
    *	ADIR() aditivo: añade al array, no 
    *          reemplaza.
    *
    *	Parámetros: los de ADIR().
    *		- El array debe pasarse por 
    *                  referencia, 
    *		   precedido por "@". Debe existir 
    *                  ya.
    *
    *	Resultado: nº de filas del array (total)
    *
    *******************************************
    function ADirAd
    
    parameters lista, esquema, atributos
    
    private onerror,nparams,n,n1,m,lista1,ncols
    
    onerror=on("error")
    
    nparams=parameters()
    do case
    case m.nparams=1
    	n1=adir(lista1)
    case m.nparams=2
    	n1=adir(lista1,m.esquema)
    case m.nparams=3
    	n1=adir(lista1,m.esquema,m.atributos)
    endcase
    
    ncols=5
    
    on error n=0
    if alen(lista,2)=m.ncols
    	n=alen(lista,1)
    else
    	n=0
    endif
    on error &onerror
    
    m=m.n+m.n1
    
    if m.n1>0
    	dimension lista[m.m, m.ncols]
    	=acopy(lista1, lista, 1, -1, m.ncols*m.n+1)
    endif
    
    return m.m
    
    
    ********************************************	
    *           Func. ESCADNUM
    ********************************************
    *	Argumento: P (cadena de caracteres)
    *	Resultado: Lógico
    *		(.T. si P corresponde a un número:
    *		sólo: cifras, no separadas por 
    *               espacios;
    *		como máximo un punto decimal; y como 
    *		máximo un signo + o - al principio)
    *
    ********************************************
    function escadnum
    
    parameter p
    
    private puntodec,lenp,i,c,yapunto
    
    p=alltrim(m.p)
    if left(m.p,1)$"-+"
    	m.p=ltrim(substr(m.p,2))
    endif
    
    puntodec=set("POINT")
    yapunto=.F.
    lenp=len(m.p)
    for m.i=1 to m.lenp
    	c=substr(m.p,m.i,1)
    	if not isdigit(m.c) ;
    		and not (m.c==m.puntodec ;
    			and not m.yapunto)
    		return .F.
    	endif
    	if m.c=m.puntodec
    		yapunto=.T.
    	endif
     
    endfor
    return .T.
    
    Marzo Varea Sanz
    Marzo@arrakis.es