[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]