Indy TIdFTP 呼叫 Abort 發生錯誤 的問題? |
缺席
|
Stallion
版主 發表:52 回覆:1600 積分:1995 註冊:2004-09-15 發送簡訊給我 |
最近寫了一個簡易版的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 發送簡訊給我 |
看了站裡很多的範例,幾乎是在呼叫PUT方法結束或失敗時,一定立即呼叫DISCONNECT方法,但這不是我要的。如果呼叫DISCONNECT方法,那我的FTP CLIENT的連線狀態不就結束了,而且其後很多的操作與程式內的善後處理都會發生錯誤!現在我暫時處理的方法是呼叫完DISCONNECT後立即呼叫一次CONNECT方法,雖然呼叫ABORT後的錯誤訊息都可以避免,但總覺得這是不正確的方法,可否請問正確的處置方式為何呢? ----------------------------------------------
We will either find a way, or make one. -Hannibal -。
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |