环境:delphi7.0
使用IdFtp上传文件,如何实现续传?
IdFTP1.Put('c:\aa.exe','aa.exe',true);
使用这条命令,如果是一次就传完,没有问题;但是中断之后,再上传,字节数就不对,不知是怎么回事?
使用IdFtp上传文件,如何实现续传?
IdFTP1.Put('c:\aa.exe','aa.exe',true);
使用这条命令,如果是一次就传完,没有问题;但是中断之后,再上传,字节数就不对,不知是怎么回事?
解决方案 »
- 赚分帖~~~
- 一个关于子类与父类的问题,急,在线==========
- Tclientsocket的使用問題
- 在delphi7中,用rave做报表我怎样通过程序给报表中的text组件赋值
- 顶级菜!TADOTABLE中的记录如何清空!!
- 能否将窗体包装在COM组件中供程序调用?
- 100分!安装自制的组件怎么在面板中显示不出来?
- 请问DELPHI怎样定义?
- 我试着写了个文本编辑器.可是编译成exe后,文本文件不能拖放到编辑区打开.打开方式也不能成功,是否须添加相应事件!!
- 如何监控到用户按下Ctrl+Alt_Delete组合键(500分)???
- 有没有南京通院的?大家联系一下,好共同进步 :)
- 师傅我是自学delphi的,如何内存搜索来做外挂的知识
你需要修改Indy的源码
APPE是可以续传的,但必须保证你的Stream的Position移动到断点的位置,Indy默认是0,当然就错误了
REST方法也是可以,但必须发送断点信息到服务器,这个看RFC959协议吧修改Indy源码是麻烦的了,自己尝试做吧另外Indy的上传过程有时候会导致UI没有反应的,放在独立线程中就可以解决这个问题能说的就这些的,剩下的自己研究吧_____________________
http://lysoft.7u7.net
Self.SendCmd('REST ' + IntToStr(ADest.Position), [350]); {Do not translate}
end;
而:
procedure TIdFTP.Get(const ASourceFile, ADestFile: string; const ACanOverwrite: boolean = false;
AResume: Boolean = false);
var
LDestStream: TFileStream;
begin
if FileExists(ADestFile) then begin
AResume := AResume and CanResume;
if ACanOverwrite and (not AResume) then begin
LDestStream := TFileStream.Create(ADestFile, fmCreate);
end
else begin
if (not ACanOverwrite) and AResume then begin
LDestStream := TFileStream.Create(ADestFile, fmOpenReadWrite);
LDestStream.Seek(0, soFromEnd);
end
else begin
raise EIdFTPFileAlreadyExists.Create(RSDestinationFileAlreadyExists);
end;
end;
end
else begin
LDestStream := TFileStream.Create(ADestFile, fmCreate);
end; try
Get(ASourceFile, LDestStream, AResume);
finally
FreeAndNil(LDestStream);
end;
end剩下的靠自己,就只能说那么多的_____________________
http://lysoft.7u7.net
const AAppend: boolean = false; const Resume: boolean = false);
var // resume mode --- by Liu Yang 2002.1.31
LSourceStream: TFileStream;
begin
LSourceStream := TFileStream.Create(ASourceFile, fmOpenRead or fmShareDenyNone);
// resume upload --- by Liu Yang 2002.1.31
if ResumeSupported and Resume
then begin
FResumeUpload := True;
FResumePoint := Size(ADestFile);
end
else FResumeUpload:=false;
// fixed end
try Put(LSourceStream, ADestFile, AAppend); finally FreeAndNil(LSourceStream); end;
end;_____________________
http://lysoft.7u7.net
const AAppend: boolean = false; const Resume: boolean = false);
var z: TZDataStream;
begin
// resume upload --- by Liu Yang 2002.1.31
if ResumeSupported and Resume
then begin
FResumeUpload := True;
FResumePoint := Size(ADestFile);
end
else FResumeUpload:=false;
// added 'MODE Z' support --- by Liu Yang 2005.5.9
if mzUpload in ModeZ then
begin
SendModeZ;
z := TZDataStream.Create(zctCompress, ASource);
try
z.UseActualSize := True;
if Length(ADestFile) = 0 then begin
InternalPut('STOU ' + ADestFile, z);
end else if AAppend then begin
InternalPut('APPE ' + ADestFile, z);
end else begin
InternalPut('STOR ' + ADestFile, z);
end;
finally
z.Free;
end;
Exit;
end else if ModeZ <> [] then SendModeS;
if Length(ADestFile) = 0 then begin
InternalPut('STOU ' + ADestFile, ASource);
end else if AAppend then begin
InternalPut('APPE ' + ADestFile, ASource);
end else begin
InternalPut('STOR ' + ADestFile, ASource);
end;
end;_____________________
http://lysoft.7u7.net
在Blues的blog,他提到可以“通过IDFTP得到服务端已经上传的部分的SIZE,然后通过文件流在本地建立剩余部分的临时文件,然后以 APPEND方式上传,传完后删除临时文件,达到上传断点续传的效果”。原文在此:DELPHI ftp 上传断点续传的实现。
我再仔细看了Indy的源码,发现不需要临时文件。可以对Blues的方法作出重大改进:
Put()方法第一个参数可以是TStream(实际上,如果是文件名的话Indy会建立Stream,然后再调用Stream的Put方法)。而且如果 Append设为True的话,Indy不会去动Stream的Position: 1. procedure TIdFTP.Put(const ASource: TStream; const ADestFile: string = '';
2. const AAppend: boolean = false);
3. ...
4. procedure TIdTCPConnection.WriteStream(AStream: TStream; const AAll: boolean = true;
5. const AWriteByteCount: Boolean = False; const ASize: Integer = 0);
6. ...
7. if AAll then begin //bianbian注:如果Append,AAll是false
8. AStream.Position := 0;
9. end;
10. // This is copied to a local var because accessing .Size is very inefficient
11. if ASize = 0 then begin
12. LStreamEnd := AStream.Size;
13. end else begin
14. LStreamEnd := ASize + AStream.Position;
15. end;
16. LSize := LStreamEnd - AStream.Position;
17. ...也就是说,先把原文件的Stream Seek到Size位置,丢给Indy即可,实现也很简单: 1. var
2. fs: TFileStream;
3. ...
4. fs := TFileStream.Create(FullFileName, fmOpenRead or fmShareDenyWrite);
5. fs.Seek(size, 0); //偏移
6. FTP.Put(fs, ExtractFileName(FullFileName), True);
7. fs.Free;