線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1716
推到 Plurk!
推到 Facebook!

Indy TIdFTP 呼叫 Abort 發生錯誤 的問題?

缺席
Stallion
版主


發表:52
回覆:1600
積分:1995
註冊:2004-09-15

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-08-30 21:09:34 IP:211.22.xxx.xxx 未訂閱
最近寫了一個簡易版的FTP Client,用途在於快速上傳下載檔案。Local端這頭使用了TShellTreeView與TShellListView顯示檔案,而Server端的檔案則顯示在一個ListView裡面,當多重選取拉ListView裡的檔案至TShellListView DragDrop時,則將Server端理的檔案下載到Local,反之做相反上傳的動作,在傳輸的期間,如果按ESC則中斷下載或上傳的動作。當下載時,按ESC可呼叫Abort方法順利中斷傳輸,而上傳時呼叫Abort雖然停止上傳,但發生一連串錯誤訊息,如Transfer Terminated Abnormally等等,本人確信兩者作法的邏輯差不多,偵錯半天找不出原因,各位先進前輩可否釋疑!我的部分CODE如下:
void __fastcall TEazyForm::LocalMachineShellListViewDragDrop(TObject *Sender, TObject *Source, int X, int Y)
{
 AnsiString FileName, LocalDirectory, RemoteFileName;
 TListItems *aItem;
 bool HasAFile = false;
 int i,j;     if ( ! FTPClientIdFTP->Connected() )
        return;
 if ( ! ( Sender->ClassNameIs("TShellListView") ) )
          return;
 if ( ! ( Source->ClassNameIs("TListView") ) )
          return;     try
 {
  this->Cursor = crHourGlass;
  ModeFunctionToolButton(true);
  ProgressGauge->Visible = true;
  MessageStatusBar->Visible = true;
  LocalMachineShellListView->Enabled = false;
  FTPDirectoryListView->Enabled = false;      aItem = FTPDirectoryListView->Items;      for ( i = 0 ; i < FTPDirectoryListView->Items->Count ; i   )
  {
   if ( aItem->Item[i]->Selected )
   {
    FileName = FTPClientIdFTP->DirectoryListing->Items[i]->FileName;
    if ( FTPClientIdFTP->DirectoryListing->Items[i]->ItemType == ditDirectory )
    {
     ::MessageBox(GetActiveWindow(),  (FileName   AnsiString(" 是個目錄,\n無法下載目錄。")).c_str(),"執行錯誤",MB_OK | MB_ICONERROR );
     continue;
    }
    LocalDirectory = LocalMachineShellListView->RootFolder->PathName();
    j = LocalDirectory.Length();
    if ( ( LocalDirectory.c_str()[ j - 1 ] == '\\' ) )
               ;
    else
           LocalDirectory  =  '\\';
    RemoteFileName =  FTPClientIdFTP->RetrieveCurrentDir();
    j = RemoteFileName.Length();
    if ( ( RemoteFileName.c_str()[ j - 1 ] == '/' ) )
           RemoteFileName  = FileName;
    else
           RemoteFileName = RemoteFileName   '/'   FileName;
    if ( FileExists( LocalDirectory   FileName ) )
         HasAFile = true;
    else
         HasAFile = false;
    try
    {
     MessageStatusBar->SimpleText = "正在下載 "   RemoteFileName   " 至 "    LocalDirectory   FileName   ",請稍後。";
     FTPClientIdFTP->TransferType = ftBinary;
     Application->ProcessMessages();
     ::Sleep(10);
     if ( HasAFile && ToBeContinuedCheckBox->Checked )
     {
      BytesToTransfer = FTPClientIdFTP->Size(RemoteFileName) - FileSizeByName(LocalDirectory   FileName);
      FTPClientIdFTP->Get(RemoteFileName,LocalDirectory   FileName,false,true);
     }
     else
     {
      BytesToTransfer = FTPClientIdFTP->Size(RemoteFileName);
      FTPClientIdFTP->Get(RemoteFileName,LocalDirectory   FileName,true);
     }
    }
    catch (...)
    {
     ::MessageBox(GetActiveWindow(),  AnsiString( "下載 "   RemoteFileName   " 發生錯誤。").c_str(),"下載錯誤",MB_OK | MB_ICONERROR );
    }
   }
   if ( AbortTransfer )
        break;
  }
 }
 __finally
 {
  LocalMachineShellListView->Refresh(); 
  FTPDirectoryListView->Enabled = true;
  LocalMachineShellListView->Enabled = true;
  MessageStatusBar->Visible = false;
  ProgressGauge->Visible = false;
  ModeFunctionToolButton(false);
  AbortTransfer = false;
  this->Cursor = crDefault;
 }
}
//---------------------------------------------------------------------------    void __fastcall TEazyForm::FTPDirectoryListViewDragDrop(TObject *Sender,TObject *Source, int X, int Y)
{
 AnsiString FileName, LocalFile, RemoteDirectory;
 TListItems *aItem;
 int i,j;     if ( ! FTPClientIdFTP->Connected() )
        return;
 if ( ! ( Sender->ClassNameIs("TListView") ) )
          return;
 if ( ! ( Source->ClassNameIs("TShellListView") ) )
          return;     aItem = LocalMachineShellListView->Items;     try
 {
  this->Cursor = crHourGlass;
  ModeFunctionToolButton(true);
  ProgressGauge->Visible = true;
  MessageStatusBar->Visible = true;
  LocalMachineShellListView->Enabled = false;
  FTPDirectoryListView->Enabled = false;      for ( i = 0 ; i < aItem->Count ; i   )
  {
   if ( aItem->Item[i]->Selected )
   {
    FileName = LocalMachineShellListView->Folders[i]->DisplayName();
    if ( LocalMachineShellListView->Folders[i]->IsFolder() )
    {
     ::MessageBox(GetActiveWindow(),  (FileName   AnsiString("是個目錄,\n無法上傳目錄。")).c_str(),"執行錯誤",MB_OK | MB_ICONERROR );
     continue;
    }
    RemoteDirectory = FTPClientIdFTP->RetrieveCurrentDir();
    j = RemoteDirectory.Length();
    if ( ( RemoteDirectory.c_str()[ j - 1 ] == '/' ) )
               ;
    else
           RemoteDirectory  =  '/';
    LocalFile = LocalMachineShellListView->Folders[i]->PathName();
    try
    {
     MessageStatusBar->SimpleText = "正在上傳 "   LocalFile   " 至 "    RemoteDirectory   ExtractFileName(LocalFile)   ",請稍後。";
     FTPClientIdFTP->TransferType = ftBinary;
     Application->ProcessMessages();
     ::Sleep(10);
     BytesToTransfer = FileSizeByName(LocalFile);
     FTPClientIdFTP->Put(LocalFile,RemoteDirectory  ExtractFileName(LocalFile),false);
    }
    catch (...)
    {
     ::MessageBox(GetActiveWindow(),  AnsiString( "上傳 "   LocalFile   " 發生錯誤。").c_str(),"上傳錯誤",MB_OK | MB_ICONERROR );
    }
    //ChangeFTPDirectory(FTPClientIdFTP->RetrieveCurrentDir());
   }
   if ( AbortTransfer )
    break;
  }
 }
 __finally
 {
  ChangeFTPDirectory(FTPClientIdFTP->RetrieveCurrentDir());
  FTPDirectoryListView->Enabled = true;
  LocalMachineShellListView->Enabled = true;
  MessageStatusBar->Visible = false;
  ProgressGauge->Visible = false;
  ModeFunctionToolButton(false);
  AbortTransfer = false;
  this->Cursor = crDefault;
 }
}    void __fastcall TEazyForm::FTPClientIdFTPWork(TObject *Sender,TWorkMode AWorkMode, const int AWorkCount)
{
 if ( AbortTransfer )
     FTPClientIdFTP->Abort(); //只要上傳呼叫Abort上傳雖停止,則有錯誤。
 ProgressGauge->Progress = AWorkCount;
 Application->ProcessMessages();
 ::Sleep(10);
}
//---------------------------------------------------------------------------
void __fastcall TEazyForm::FormKeyPress(TObject *Sender, char &Key)
{
 if ( ! FTPClientIdFTP->Connected() )
      return;
 if ( ! TransferringData )
      return;
 if ( Key != 27 )
      return;
 if ( ::MessageBox(GetActiveWindow(),AnsiString("確定停止傳輸嗎?").c_str(),"停止傳輸",MB_YESNO | MB_ICONINFORMATION ) == IDYES )
      AbortTransfer = true;
}
---------------------------------------------- We will either find a way, or make one. -Hannibal -。 發表人 - stallion 於 2005/08/30 21:16:35
Stallion
版主


發表:52
回覆:1600
積分:1995
註冊:2004-09-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-08-31 18:21:00 IP:211.22.xxx.xxx 未訂閱
看了站裡很多的範例,幾乎是在呼叫PUT方法結束或失敗時,一定立即呼叫DISCONNECT方法,但這不是我要的。如果呼叫DISCONNECT方法,那我的FTP CLIENT的連線狀態不就結束了,而且其後很多的操作與程式內的善後處理都會發生錯誤!現在我暫時處理的方法是呼叫完DISCONNECT後立即呼叫一次CONNECT方法,雖然呼叫ABORT後的錯誤訊息都可以避免,但總覺得這是不正確的方法,可否請問正確的處置方式為何呢? ---------------------------------------------- We will either find a way, or make one. -Hannibal -。
系統時間:2024-05-04 16:06:09
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!