Solved

Simple Thread

Posted on 1998-07-02
19
275 Views
Last Modified: 2011-09-20
I have a sub that is copying files using CopyFile(PChar(source), PChar(dest), False) (Windows unit).
The sub is copying a lot of files so I want to convert it so it is another thread so the user is able to stop it in any moment. Can someone help me with this?
I'd like to mention that I wouldn't want to use any other procedure that isn't similar to CopyFile, like SHFileOperation for example (it's displaying the dialog with the flying files...)
Big thanks as ever to you guys. Regards, bosism@netvision.net.il
0
Comment
Question by:Matvey
  • 8
  • 4
  • 3
  • +2
19 Comments
 
LVL 4

Expert Comment

by:d003303
Comment Utility
If you put CopyFile in a thread, the user will only be able to stop the operation after the function returns, i.e. the current file is finished with copying. If this is a large file and the user cancels copying at the beginning of the copy process, it will take quite a while until his intervention will take action.
To stop copying at any point, you will need to set up a custom copy procedure that frequently checks the status back, e.g. if you copy in 4K buffers, after a buffer is copied.

Slash/d003303

Slash/d003303
0
 
LVL 4

Expert Comment

by:d003303
Comment Utility
??? signed twice, need some coffee...
0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
3 ways to copy a file :

Q:  How do I copy a file?

A:  Here are three ways:

{This way uses a File stream.}
Procedure FileCopy( Const sourcefilename, targetfilename: String );
Var
  S, T: TFileStream;
Begin
  S := TFileStream.Create( sourcefilename, fmOpenRead );
  try
    T := TFileStream.Create( targetfilename,
                             fmOpenWrite or fmCreate );
    try
      T.CopyFrom(S, S.Size ) ;
    finally
      T.Free;
    end;
  finally
    S.Free;
  end;
End;

{This way uses memory blocks for read/write.}
procedure FileCopy(const FromFile, ToFile: string);
 var
  FromF, ToF: file;
  NumRead, NumWritten: Word;
  Buf: array[1..2048] of Char;
begin
  AssignFile(FromF, FromFile);
  Reset(FromF, 1);              { Record size = 1 }
  AssignFile(ToF, ToFile);      { Open output file }
  Rewrite(ToF, 1);              { Record size = 1 }
  repeat
    BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
    BlockWrite(ToF, Buf, NumRead, NumWritten);
  until (NumRead = 0) or (NumWritten <> NumRead);
  CloseFile(FromF);
  CloseFile(ToF);
end;

{This one uses LZCopy, which USES LZExpand.}
procedure CopyFile(FromFileName, ToFileName: string);
var
  FromFile, ToFile: File;
begin
  AssignFile(FromFile, FromFileName); { Assign FromFile to FromFileName }
  AssignFile(ToFile, ToFileName);     { Assign ToFile to ToFileName }
  Reset(FromFile);                    { Open file for input }
  try
    Rewrite(ToFile);                  { Create file for output }
    try
      { copy the file an if a negative value is returned }
      { raise an exception }
      if LZCopy(TFileRec(FromFile).Handle, TFileRec(ToFile).Handle) < 0
        then
        raise EInOutError.Create('Error using LZCopy')
    finally
      CloseFile(ToFile);  { Close ToFile }
    end;
  finally
    CloseFile(FromFile);  { Close FromFile }
  end;
end;



0
 
LVL 3

Author Comment

by:Matvey
Comment Utility
Thanks, I know about these methods. In fact there is a dozen of components for copying files but none that works like a thread.

Let's say I'm copying 100 files using some copy procedure inside a loop. It doesn't metter  right now what method to use. The thing I want is to make this procedure run as an indepandent thread so the user can interact with the rest of the application and at least press the abort button. Right now let's not think about when the process will be actually interupted - may it be even after the current CopyFile finishes - nevermind. Right now I want to know how do I just make a simple thread like this. Can you help guys?
0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
Matvey, have you already looked at the borland example?

DELPHI 3.0/DEMOS/THREADS

Zif.
0
 
LVL 3

Author Comment

by:Matvey
Comment Utility
Yup. I've made almost an exact copy of it with my procedure, but it didn't work.
0
 
LVL 1

Expert Comment

by:Greedy
Comment Utility
ok I'll give you a quicky example on how to build a thread but my example will build one thread for every 8bits of a file to transfer and it will fist build all the threads and then they will all be executed at the same time...just kidding...OK first thing I must ask you is do you want you threads to be spawned using the borland TThread class or do you want to use all API...to bad because it's not your desicion on what I'm going to type..this time anyway...I'm going to type a quick Thread Wizard example...and then I'll try it to see if it works (eats up more of my time that way)...

1) Select the Thread Wizard from the Object Repository. (File | New -> New -> Thread Object) Use the dialog box it displays to define a class name for your thread.  In responce, the Thread Wizard generates a new unit and adds it to your project.

2) Define the code that will run within the thread.  This code is primarily associated with the Execute method of your new thread class, which overrides the inherited Execute method.  Look for the  { Place thread code here }

3) Whithin the thread's Execute method, optionally provide for the testing of the thread's Terminated propert, and to exit the Execute method if terminated is True.  With a thread that has a short and normal course of execution after which it terminates on its own, this is not necessary.

4) Create an instance of your thread object using the Create constructor.  The thread can be created in suspended mode if you need to modify one or more of its properties prior to executing the thread, or it can be created as a running thread.

5) Optionally control the priority of the thread.

6) Optional set the thread object's FreeOnTerminate property to force the thread to call its Free method when the thread terminates.

7) Optional assign an event handler to the thread objects OnTerminate event property.  Within this event handler you write code that is executed when the thread terminates.

8) Provide for the calling of the thread's Terminate method (which set's the thread's Terminate property to True), if the thread does not otherwise terminate on its own.

9) If you do not set the thread object's FreeOnTerminate property to True, ensure that you call the thread's Free method prior to exiting the primary thread of execution.

I'll also send you a little demo program to look at.

0
 
LVL 1

Expert Comment

by:Edo082297
Comment Utility
Hi Matvey,

   I am currently working on a class that among other things, does exactly what you need. For the file copying part, I instantiated a thread in a very similar manner to what Greedy has posted. It works fine. What, more specifically, doesn't work in your case?

Edo
0
 
LVL 3

Author Comment

by:Matvey
Comment Utility
Hi Edo, can you please send me the thing you say works? -Thanks
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 3

Author Comment

by:Matvey
Comment Utility
bosism@netvision.net.il
0
 
LVL 3

Author Comment

by:Matvey
Comment Utility
hi there everybody, Greedy helped me to get this working so first of all big thanks again to him. Of course I thank everybody else, and I'd like to give some points to Greedy.
0
 
LVL 3

Author Comment

by:Matvey
Comment Utility
Hi there everybody, Greedy helped me to get this working so first of all big thanks again to him. Of course I thank everybody else, and I'd like to give some points to Greedy.
0
 
LVL 4

Expert Comment

by:d003303
Comment Utility
Sure, no prob.
0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
Sure no problem, but why did you have to post this comments twice? This doesn't make my day... ;-) Oops, flipping again, sorry ... gone.
0
 
LVL 3

Author Comment

by:Matvey
Comment Utility
Heh, I see it really posted the comment twice. I saw things like this before here, even twice posted questions... must be some bug...
0
 
LVL 1

Accepted Solution

by:
Greedy earned 30 total points
Comment Utility
It's not a bug, it's your freekishly long fingers hitting the Submit button several times...hit back and then hit refresh after the Submit and normaly you get a box that says "repost form data?" but for some reason NutScrape becomes violent...but any way for all you answer seekers out there just email Matvey there and you'll be happy...what does flipping mean there Ziffy if this like a side effect from excesive caffine gobbeling?  I keep invisioning you in a zero gravity envirornment but it seams you have no arms or legs just a head and a potato like body floating around with a large twig in your mouth that you use to type with however because the velcro strap that holds you to your "companion toilet" has broken you now wack your head continuosly on the monitor to your MAC II-C...oh well at least your depraved condition brings hurmor to the rest of us :)

0
 
LVL 1

Expert Comment

by:Edo082297
Comment Utility
Hi Matvey

   Well done, Greedy. Matvey, sorry I couldn`t send you the code for the thread, I wrote it for work :)

Edo
0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
Greedy, correctly, that's flipping, can't explain it better...
0
 
LVL 3

Author Comment

by:Matvey
Comment Utility
Heh... thanks all again, and I'll post the code edited from what Greedy sent me. It wasn't tested yet for extreme contidions like high heat or messy drives and drivers, but if you provide it with nice directories and don't treat it bad, it should be atempting to do what it's meant to do:


    unit UThread;

    interface

    uses
      Classes, Dialogs, Windows, SysUtils;

    type
      FileCopy = class(TThread)
      private
        FFrom: String;
        FTo: string;
        FMask: string;
        FRecursiveCopy: Boolean;
        procedure CopyFiles(path, mask, destpath : AnsiString; Recursive: Boolean);
      protected
        procedure Execute; override;
      Published
        Property FromDir: String read FFrom write FFrom;
        Property ToDir: String read FTo write FTo;
        Property Mask: String read FMask write FMask;
        property RecursiveCopy: Boolean read FRecursiveCopy write FRecursiveCopy;
      end;

    implementation

    {$I-}
    procedure FileCopy.CopyFiles(path, mask, destpath : AnsiString; Recursive: Boolean);
    var
      srRes : TSearchRec;
      iFound : Integer;
    begin
      if path[Length(path)] <> '\' then path := path +'\';
      if destpath[Length(destpath)] <> '\' then destpath := destpath +'\';

      MKDir(destpath);

      if recursive then
      begin
        iFound := FindFirst( path + '*.*', faAnyfile, srRes );
        while iFound = 0 do
        begin
          if ( srRes.Name <> '.' ) and ( srRes.Name <> '..' ) then
            if srRes.Attr and faDirectory > 0 then
              CopyFiles(path + srRes.Name, mask, destpath + srRes.Name, Recursive);
          iFound := FindNext(srRes);
        end;
        FindClose(srRes);
      end;

      iFound := FindFirst(path+mask, faAnyFile-faDirectory, srRes);
      while iFound = 0 do
      begin
        if ( srRes.Name <> '.' ) and ( srRes.Name <> '..' ) and ( srRes.Name <> '' ) then
          CopyFile(PChar(path+srRes.Name), PChar(destpath+srRes.Name), False);
        iFound := FindNext(srRes);
      end;
      FindClose( srRes );
    end;

    procedure FileCopy.Execute;
    begin
      CopyFiles(FFrom, FMask, FTo, FRecursiveCopy);
    end;

    end.



You activate the thing like this:

    var
      MyThread: FileCopy;
    begin
    MyThread := FileCopy.Create(True);
    MyThread.FreeOnTerminate := True;
    MyThread.FromDir := Form1.DirectoryListBox1.Directory;
    MyThread.Mask := Form1.FileListBox1.Mask;
    MyThread.ToDir := Form1.DirectoryListBox2.Directory;
    Mythread.RecursiveCopy := Form1.CheckBox4.Checked;
    MyThread.Resume;
    end;

Cheers, Matvey
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This video discusses moving either the default database or any database to a new volume.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now