[Back to FILES SWAG index] [Back to Main SWAG index] [Original]

    {
     GH> Here is what my Waite's group book says word for word, and I haven't
     GH> an idea on how to do this.
     GH> "23H   Filesize. Prior to invoking this function, DS:DX is set to
     GH> point to the segment: offset address of an unopened file control
     GH> block(FCB)."
     GH> Now there is my problem, I need to know how to do the DS:DX thing to
     GH> place a file name in it, so I can check that _certain_ file for its
     GH> size.
     GH> If anyone knows how to do this, could you lend a hand.

    Refrain from using the old-style file access methods, i.e, those using
    FCB's. Not only are they "frowned upon" by Microsoft, worse: they can
    only work with files located in the current directory.
    Use the file handle methods instead.
    }

       PROGRAM The_Size_Of_Files;

       USES dos;

       { -- Both functions below wil return the size of a file. In case of an
         -- error, the return value is -1.
         -- Note that their parameters are of different types. }

       FUNCTION Size_of_file(CONST fn: PathStr): longint;
       VAR SR: SearchRec;
       BEGIN findfirst(fn, AnyFile - VolumeID - Directory, SR);
             IF DosError = 0
             THEN Size_of_file:=SR.Size
             ELSE Size_of_file:=-1
                  { -- Or some other clearly nonsensical value. }
       END;

       FUNCTION AsmFilesize(CONST F): longint;
       { -- F MUST be a Text or File-variable. }
       ASSEMBLER;
       { --  LSEEK ÄÄ Move file read/write pointer (Func 42)

         -- INT 21 - DOS 2+
         --    AH = 42h
         --    AL = method
         --       00h offset from beginning of file
         --       01h offset from present location
         --       02h offset from end of file
         --   BX = file handle
         --   CX:DX = offset in bytes

         -- Return: CF set on error
         --       AX = error code (01h,06h) (see AH=59h)
         --         CF clear if successful
         --       DX:AX = new absolute offset from beginning of file }
       ASM mov ah, $42
           mov al, 2

           les di, F         { -- Now ES:DI holds the address of F. }
           mov bx, es:[di]   { -- BX now holds the filehandle of F; look up
                               -- types Dos.TextRec and Dos.FileRec for an
                               -- explanation. }

           xor cx, cx
           xor dx, dx        { -- CX and DX are now both zero. }

                             { -- In effect, the file pointer is to be moved
                               -- to the end of the file. }

           int $21
           jnc @@Exit        { -- Did we succeed ? }

           mov dx, $FFFF     { -- NO: so make the functionresult (a Longint is }
           mov ax, $FFFF     { --     returned in DX:AX) = -1.                 }

       @@Exit:               { -- YES: quit without further ado. }
       END;

       { -- Main: }

       VAR fn: PathStr;
           F : FILE;

       BEGIN write('PLease enter filename: '); readln(fn);
             assign(F, fn); {$I-} reset(F, 1); {$I+}
             IF IOresult <> 0
             THEN BEGIN writeln(#7'No such file ...'); halt(2) END;

             writeln('FileSize : ', FileSize(F));
             writeln('FindFirst: ', Size_of_file(fn));
             writeln('LSeek    : ', AsmFilesize(F))
       END.

    Perhaps it would be interesting to see which method is fastest.

    The ONLY situation in which you absolutely must use FCBs is setting the
    volume label on a disk.

[Back to FILES SWAG index] [Back to Main SWAG index] [Original]