我做了一个简单的多线程程序,主要是有多个任务,实现无间断定时把任务中定的一个目录里的内容复制到另一个目录。我将目录的程序作成一个单独的函数,现在遇到的问题是:如果有两个任务同时在执行线程,则不能将目录里的内容复制到另一个目录里。关键代码如下:
// UTrdBatchMove unit
procedure TrdBatchMove.Execute;
begin
  while true do
  begin
    FrmMain.LogBusyOrIdle(iTrdIndex, iTimes, 1, strMName);
    CopyDir;
    Inc(iTimes);
    FrmMain.LogBusyOrIdle(iTrdIndex, iTimes, 0, strMName);
    Sleep(iPause * 1000 * 60); // 1 sec
  end;
end;procedure TrdBatchMove.CopyDir();
var
  d: TDate;
  arr: array[1..7] of string;
  i: integer;
begin
  if Length(strFromDir) <= 0 then
    exit;
  if DirectoryExists(strToDir) then
  begin
    DoCopyDir(strFromDir, strToDir, bIncSubDir);
  end else
    FrmMain.LogBusyOrIdle(iTrdIndex, 0, -2, strMName);
end;// 复制函数的unit
function DoCopyDir(sDirName: string; sToDirName: string;
    IncSubDir : Boolean = true): Boolean;
var
  hFindFile: Cardinal;
  t, tfile: string;
  FindFileData: WIN32_FIND_DATA;
begin
  if DirectoryExists(sDirName) then
  begin
    try
      ChDir(sDirName);
      ForceDirectories(sToDirName);
      hFindFile := FindFirstFile('*.*', FindFileData);
      if hFindFile <> INVALID_HANDLE_VALUE then
      begin
        repeat
          tfile := FindFileData.cFileName;
          if (tfile = '.') or (tfile = '..') then
            Continue;
          if (FindFileData.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY) and
            IncSubDir then
          begin
            t := sToDirName + '\' + tfile;
            if not DirectoryExists(t) then
              ForceDirectories(t);
            if sDirName[Length(sDirName)] <> '\' then
              DoCopyDir(sDirName + '\' + tfile, t)
            else
              DoCopyDir(sDirName + tfile, sToDirName + tfile);
          end
          else
          begin
            t := sToDirName + '\' + tFile;
            CopyFile(PChar(tfile), PChar(t), false);
            FrmMain.LogStatus(t);
          end;
        until FindNextFile(hFindFile, FindFileData) = false;
        FindClose(hFindFile);
      end
      else
      begin
        FrmMain.LogBusyOrIdle(0, 0, -1, 'invl :' + sToDirName);
        result := false;
        exit;
      end;
      ChDir('d:');
    except on e: Exception do
      FrmMain.LogBusyOrIdle(0, 0, -1, e.Message);
    end;
  end;
  result := true;
end;

解决方案 »

  1.   

    这种程序不用写的,有一个软件叫smartsync的,巨牛,不光可以本机拷贝,也支持网络拷贝。
      

  2.   

    说实话,楼主的这个复制目录的方法有点土
    windows提供了shell api,简单又稳定,不需要这么麻烦自己去做.
    相关api: SHFileOperation 
    Header shellapi.h 
    Import library shell32.lib 
    ==========广告签名============
    http://shop33712512.taobao.com
    淘宝店,专卖化妆品、自家蜂产品
    ==========广告签名============
      

  3.   

    复制的时候建立临界区吧
    var
      CS:TRTLCriticalSection;
    调用线程前初始化:
    InitializeCriticalSection(CS);
    调用后销毁:
    DeleteCriticalSection(CS);procedure TrdBatchMove.Execute;
    begin
    EnterCriticalSection(CS);    //只允许一个线程操作
    while true do
    begin
    FrmMain.LogBusyOrIdle(iTrdIndex, iTimes, 1, strMName);
    CopyDir;
    Inc(iTimes);
    FrmMain.LogBusyOrIdle(iTrdIndex, iTimes, 0, strMName);
    Sleep(iPause * 1000 * 60); // 1 sec
    end;
    LeaveCriticalSection(CS); 
    end;
      

  4.   

    smartsync我下了,不能达到我的要求,它只能每天,每周,我要几分钟就轮询一次。TO:Hellboy(int argc, char* argv[]) 
    你说土,我承认,但是从我想的来说,这种方式挺合理的,本来我是想判断文件是否时间一致就不做覆盖复制,由于多线程取得文件时间有问题,就沿用这个写好的方法。另外你说的也不清楚。TO:terence4444(T4)
    创建临界区,可以倒是可以,可我不知道为什么查找复制文件的方法,怎么就不能用多线程调用呢???
      

  5.   

    我把目录复制的按Hellboy(int argc, char* argv[]) 说的刚改了,观察一段时间,我想这样不应该有问题吧。不过有些地方还是要通过文件逐个复制