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

    {I've been trying to figure out how to do a fairly fast copy
     in pascal.  It doesn't have to be faster then Dos copy, but
     I definatly DON'T want to shell out to Dos to do it!
     I've got the following working... in the IDE of Turbo 6.0!
     If I compile it, it wont work at all.  ALSO... If you COMP
     the Files to check For errors, They are there.  (UGH!)
     (ie, it isn't a perfect copy!)
     The thing is I want to get as much as I can in each pass!
     (But turbo has limits!)
     Heres my code... Just rough, so no Real comments.
    }

    Program Copy (InFile, OutFile);

    Uses Dos;

    Var
       I, Count, BytesGot : Integer;
       BP : Pointer;
       InFile,OutFile:File;

       FI,FO : Word;

       Path,
       FileName : String[80];

       DirInfo : SearchRec;
       BaseRec, RecSize : longInt;

    begin
       FileName := ParamStr(1);             {Set the SOURCE as the first ParamSTR}
       Path := ParamStr(2);                 {Set the Dest.  as the 2nd paramSTR}

       If paramCount = 0 Then
          begin
               Writeln('FastCopy (C) 1993 - Steven Shimatzki');
               Writeln('Version : 3.0   Usage: FastCopy <Source> <Destination>');
               Halt(1);
          end;

       FindFirst(FileName,Archive,DirInfo);

       If DirInfo.Name <> '' Then
       begin

           RecSize := MaxAvail - 1024;  {Get the most memory but leave some}
           BaseRec := RecSize;

           If RecSize > DirInfo.Size Then      {If a "SMALL" File, gobble it up}
               RecSize := DirInfo.Size;        {In one pass!  Size = Recordsize}

           Count := DirInfo.Size Div RecSize;  {Find out how many Passes!}

           GetMem (Bp, RecSize);   {Allocate memory to the dynamic Variable}

           Assign (InFile,FileName);       {Assign the File}
           Assign (OutFile,Path);          {Assign the File}

           Filemode := 0;     {Open the INFile as READONLY}

           Reset(InFile,RecSize);      {open the input}
           ReWrite(OutFile,RecSize);   {make the output}

           For I := 1 to Count do    {Do it For COUNT passes!}
           begin

                {$I-}
                Blockread(InFile,BP^,1,BytesGot);   {Read 1 BLOCK}
                {$I+}

                BlockWrite(outFile,BP^,1,BytesGot);   {Write 1 BLOCK}

                If BytesGot <> 1 Then
                   Writeln('Error!  Disk Full!');

           end;

    {If not all read in, then I have to get the rest seperatly!  partial Record!}

           If Not ((Count * RecSize) = DirInfo.Size) Then
           begin
                RecSize := (DirInfo.Size - (Count * RecSize)) ;
                           {^^^ How much is left to read? get it in one pass!}

                FreeMem(Bp, BaseRec);      {Dump the mem back}
                GetMem(Bp, RecSize);       {Get the new memory}

                FileMode := 0;         {Set input For readonly}

                Reset (InFile,1);

                Filemode := 2;         {Set output For Read/Write}

                Reset (OutFile,1);

                Seek(InFile, (Count * BaseRec));   {Move to old location}
                Seek(OutFile, (Count * BaseRec));{ same }

                FI := FilePos(InFile);    {Just used to see where I am in the File}
                FO := FilePos(OutFile);   {Under the Watch Window... Remove later}

                {$I-}
                BlockRead(InFile,Bp^,RecSize,BytesGot);    {REad the File}
                {$I+}

                BlockWrite(OutFile,Bp^,RecSize,BytesGot);  {Write the File}

           end;

           Close(OutFile);
           Close(InFile);

           FreeMem (Bp,RecSize);

       end;

    end.

    {
    You don't close the input- and output File when your finished With the
    first count passes. Maybe your last block will not be written to disk,
    when you reopen the outputFile For writing. I can't see another problem
    right now.

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