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