这两天一直在研究Indy的TIdFTP,用来实现FTP操作。
完整的代码请到此下载:
http://www.mini188.com/showtopic-855.aspx
因为是Delphi7自带的,好像有许多 BUG,使用时也确实是这样,总是有些奇怪的问题出现。但简单的功能还是实现了。使用他的Put和Get方法可以完成基本的操作。
简单代码如下:
下载代码
- //下载,支持断点续传
- procedure TForm1.Button5Click(Sender: TObject);
- var
- stream: TFileStream;
- sDownToFileName: string;
- bIsDir: Boolean;
- sDir: string;
- begin
- if ListView1.Selected = nil then Exit;
- if not IdFTP1.Connected then
- raise Exception.Create('未连接FTP服务器');
- if SaveDialog1.Execute then
- begin
- sDownToFileName := SaveDialog1.FileName;
- if FileExists(sDownToFileName) then
- stream := TFileStream.Create(sDownToFileName, fmOpenWrite)
- else
- stream := TFileStream.Create(sDownToFileName, fmCreate);
- try
- if ListView1.Items.Count > 0 then //ListView1是从FTP服务器取的当前目录列表
- begin
- sDir := GetNameFromDirLine(FFtpDirList.Strings[ListView1.ItemIndex], bIsDir);//取得当前选中的是否为文件
- if not bIsDir then
- begin
- pb1.Max := IdFTP1.Size(sDir);//pb1是ProgressBar控件,进度条
- pb1.Position := stream.Size;
- stream.Position := stream.Size;//如果本地文件存在将位置移动到尾部
- IdFTP1.Get(sDir, stream, True);//这个不就说了 吧,最后一个参数使用True就表明是支续传
- ChageDir(IdFTP1.RetrieveCurrentDir);
- end;
- end;
- finally
- FreeAndNil(stream);
- end;
- end;
- end;
- function TForm1.GetNameFromDirLine(Line: string; var IsDirectory: Boolean): string;
- var
- i: Integer;
- DosListing: Boolean;
- begin
- IsDirectory := Line[1] = 'd';
- DosListing := false;
- for i := 0 to 7 do begin
- if (i = 2) and not IsDirectory then
- begin
- //IsDirectory := Copy(Line, 1, Pos(' ', Line) - 1) = '<DIR>';
- IsDirectory := Copy(Line, 1, Pos(' ', Line) - 1) = '<DIR>';
- if not IsDirectory then
- DosListing := Line[1] in ['0'..'9']
- else
- DosListing := true;
- end;
- Delete(Line, 1, Pos(' ', Line));
- While Line[1] = ' ' do Delete(Line, 1, 1);
- if DosListing and (i = 2) then break;
- end;
- Result := Line;
- end;
复制代码 上传的代码- procedure TForm1.PutFile(const AFileName: string);
- var
- mm: TFileStream;
- iFileSize: Int64;
- begin
- mm := TFileStream.Create(AFileName, fmOpenRead);
- try
- pb1.Max := mm.Size;
- iFileSize := IdFTP1.Size(ExtractFileName(AFileName));
- if iFileSize <> -1 then// 如果不是-1表明服务器上有同名文件,则需要续传
- begin
- pb1.Position := iFileSize;
- mm.Position := iFileSize;
- IdFTP1.Quote('REST ' + FloatToStr(iFileSize));
- IdFTP1.Put(mm, ExtractFileName(AFileName), True);//最后一个参数就是打开Append,这样可以不重新上传文件了
- end
- else
- IdFTP1.Put(mm, ExtractFileName(AFileName));
- ChageDir(IdFTP1.RetrieveCurrentDir);
- finally
- FreeAndNil(mm);
- end;
- end;
复制代码上面的代码只是简单的实现了上传和下载,在测试过程中下载比较顺利,但是上传时如果中途中断了操作会报一个异常。必须断开连接重新连接上后再传就可以了。
在Delphi2009中也测试了一下新版本的Indy,发现有个更郁闷的问题,IdFTP.List读取过来的中文都是乱码。也不知道是为什么,看代码应该是字符编码问题,但不知道如何解决。更新了字符编码也无用。