LIB$Find_File RTL function

This routine can be used in a loop to locate specific files, and the returned filespec can be used in all kinds of processing. If you look for a specification using a wildcard, be sure to pass a context variable, it is a handle for retrieving the next filespecification that matches the mask passed.

But keep this in mind: The first call, with context = 0, will scan the directory for all files that match the condition - that is: those present 'at that time'. You won't find newer ones!

To demonstrate compile and link the following program ( I named it FINFDILE.PAS):

[INHERIT (
    'SYS$LIBRARY:STARLET.PEN',
    'SYS$LIBRARY:PASCAL$STR_ROUTINES.PEN',
    'SYS$LIBRARY:PASCAL$LIB_ROUTINES.PEN')]
 
PROGRAM FINDFILEDEMO (OUTPUT);
 
{ **************************************************************************** }
PROCEDURE P_LOGLINE (
    D_LINE : VARYING [$U1] OF CHAR );
 
VAR
    V_LOGFILE : TEXT;
    V_DATETIME : PACKED ARRAY [1..11] OF CHAR;
    V_TXTSNDCNT : VARYING [5] OF CHAR ;
 
BEGIN
    OPEN (V_LOGFILE,'FINDFILE.LOG',UNKNOWN,120,ERROR := CONTINUE);
    IF STATUS (V_LOGFILE) = 0 THEN
    BEGIN
        EXTEND (V_LOGFILE);
    END ELSE
    BEGIN
        OPEN (V_LOGFILE,'FILEFIND.LOG',NEW,120) ;
        REWRITE (V_LOGFILE);
    END;
 
    TIME (V_DATETIME);
    WRITELN (V_LOGFILE,V_DATETIME,' ', D_LINE) ;
    CLOSE (V_LOGFILE);
END;
 
{ **************************************************************************** }
 
VAR
    V_RESNAME : PACKED ARRAY [1..64] OF CHAR;
    V_CONTEXT : UNSIGNED;
    V_FILESPEC : VARYING [64] OF CHAR;
    V_LOGLINE : VARYING[80] OF CHAR ;
    V_STATUS : INTEGER ;
    V_CNT : INTEGER ;
    V_FILES : [WORD] 0..65535 ;
    V_DSP : VARYING[11] OF CHAR ;
 
BEGIN
 
    P_LOGLINE ('');
    P_LOGLINE ('Start FILEFIND');
    V_Cnt := 50 ;
    V_FILESPEC := '*.NEW';
    REPEAT
        WRITEV (V_DSP, 51 - V_CNT) ;
        P_LOGLINE ('Start Loop' + V_DSP);
        V_CONTEXT := 0;
        V_FILES := 0 ;
        REPEAT
            V_STATUS := LIB$FIND_FILE (FILESPEC := V_FILESPEC,
                                       RESULTANT_FILESPEC := V_RESNAME,
                                       CONTEXT := V_CONTEXT );
            IF (NOT ODD (V_STATUS)) AND
               (LIB$MATCH_COND (V_STATUS,RMS$_FNF) = 0) AND
               (LIB$MATCH_COND (V_STATUS,RMS$_NMF) = 0) THEN LIB$SIGNAL (V_STATUS);
            IF ODD (V_STATUS) THEN
            BEGIN
                V_RESNAME := SUBSTR (V_RESNAME,1,(INDEX (V_RESNAME,';'))) ;
                V_FILES := V_FILES + 1 ;
                P_LOGLINE ('File ' + V_ResName);
                LIB$WAIT (1.5) ;
                RENAME_FILE (V_RESNAME,'*.SEND');
            END;
 
        UNTIL (NOT ODD (V_STATUS)) ;
        V_STATUS := LIB$FIND_FILE_END (CONTEXT := V_CONTEXT);
        IF NOT ODD (V_STATUS) THEN LIB$SIGNAL (V_STATUS);
 
        WRITEV (V_DSP, V_FILES) ;
        P_LOGLINE ('Stop Loop, files found = ' + V_DSP);
        IF V_FILES > 0 THEN LIB$WAIT (29.0) ELSE LIB$WAIT (0.5) ;
        V_Cnt := V_Cnt-1 ;
    UNTIL V_CNT =0 ;
 
    WRITEV (V_LOGLINE,'Program stopped');
    P_LOGLINE (V_LOGLINE);
END.

and create this procedure (I named it CRENEW.COM), creating an arbitrary number of files, about 3 a second:

$ Num=f$integer(p1)
$ if num .eq. 0 then num=10
$loop:
$ fd = f$cvtime("","COMPARISON","DATE") - "-" - "-"
$ ft = f$cvtime("","COMPARISON","TIME") - ":" - ":" - "."
$ crea 'fd''ft'.NEW
$ wait 00:00:00.30
$ num = Num -1
$ if num .gt. 0 then goto loop
$ write sys$output "done"

Next, execute these commands:

$ SPAWN/NOWAIT @CRENEW
$ run findfile

The log will show that it takes more than one iteration of LIB$FIND_FILE to process all files:

12:05:27.10
12:05:27.15 Start FILEFIND
12:05:27.18 Start Loop         1
12:05:27.22 File TKSPROD:[TKSALG.WILLEM]2008121012052420.NEW;
12:05:28.85 File TKSPROD:[TKSALG.WILLEM]2008121012052470.NEW;
12:05:30.47 File TKSPROD:[TKSALG.WILLEM]2008121012052507.NEW;
12:05:32.10 File TKSPROD:[TKSALG.WILLEM]2008121012052542.NEW;
12:05:33.74 File TKSPROD:[TKSALG.WILLEM]2008121012052579.NEW;
12:05:35.39 File TKSPROD:[TKSALG.WILLEM]2008121012052630.NEW;
12:05:37.02 File TKSPROD:[TKSALG.WILLEM]2008121012052666.NEW;
12:05:38.62 File TKSPROD:[TKSALG.WILLEM]2008121012052701.NEW;
12:05:40.22 Stop Loop, files found =          8
12:06:09.28 Start Loop         2
12:06:09.34 File TKSPROD:[TKSALG.WILLEM]2008121012052740.NEW;
12:06:10.96 File TKSPROD:[TKSALG.WILLEM]2008121012052778.NEW;
12:06:12.60 Stop Loop, files found =          2
12:06:41.66 Start Loop         3
12:06:41.72 Stop Loop, files found =          0
...

Do the same with 1000 files, and you'll see someting like this, but all 1000 messages have been handled in 5 or 6 iterations...

FindFileSS (last edited 2008-12-10 12:55:24 by admin)