麻烦哪位老兄帮我看看这个关于用wininet.dll函数通过ftp方式取文件的问题! (100分)

G

gdhyj

Unregistered / Unconfirmed
GUEST, unregistred user!
我的本意是通过点击BitBtn1按钮从192.168.1.1的ftp服务器上取回三个文件:file1,file2,file3
但到取第二个文件的时候提示找不到文件,而我单独取哪个文件都可以成功(说明服务器上有文件)。

function FtpDownloadFile(hNet,hFTP: HINTERNET; ftpFile, TargetFile: string; ProgressBar: TProgressBar): Boolean;

function FmtFileSize(Size: Integer): string;
begin
if Size >= $F4240 then
Result := Format('%.1f', [Size / $F4240]) + ' Mb'
else
if Size < 1000 then
Result := IntToStr(Size) + 'bytes'
else
Result := Format('%.1f', [Size / 1000]) +' Kb';
end;
const
READ_BUFFERSIZE = 4096; // or 256, 512, ...
var
hFile: HINTERNET;
buffer: array[0..READ_BUFFERSIZE - 1] of Char;
bufsize,dwBytesRead,fileSize: DWORD;
sRec: TWin32FindData;
LocalFile: File;
begin
Result :=False;

{ Read size of file }
if FtpFindFirstFile(hFTP, PChar(ftpFile), sRec, 0, 0) <> nil then
begin
fileSize := sRec.nFileSizeLow;
// fileLastWritetime := sRec.lastWriteTime
end else
begin
ShowMessage(Format('Cannot find file',[ftpFile]));
Exit;
end;

{ Open the file }
hFile := FtpOpenFile(hFTP, // Handle to the ftp session
PChar(ftpFile), // filename
GENERIC_READ, // dwAccess
FTP_TRANSFER_TYPE_BINARY, // dwFlags
0); // This is the context used for callbacks.

if hFile = nil then
begin
Exit;
end;

{ Create a new local file }
AssignFile(LocalFile, TargetFile);
{$i-}
Rewrite(LocalFile, 1);
{$i+}

if IOResult <> 0 then
begin
InternetCloseHandle(hFile);
Exit;
end;

dwBytesRead := 0;
bufsize := READ_BUFFERSIZE;

while (bufsize > 0) do
begin
Application.ProcessMessages;

if not InternetReadFile(hFile,
@buffer, // address of a buffer that receives the data
READ_BUFFERSIZE, // number of bytes to read from the file
bufsize) then Break; // receives the actual number of bytes read

if (bufsize > 0) and (bufsize <= READ_BUFFERSIZE) then
BlockWrite(LocalFile, buffer, bufsize);
dwBytesRead := dwBytesRead + bufsize;

{ Show Progress }
ProgressBar.Position := Round(dwBytesRead * 100 / fileSize);
Form1.Label1.Caption := Format(' %d %% %s of %s',[ProgressBar.Position,FmtFileSize(dwBytesRead),FmtFileSize(fileSize)]);
//Form1.Label1.Caption := Format('%s of %s / %d %%',[FmtFileSize(dwBytesRead),FmtFileSize(fileSize) ,ProgressBar.Position]);
end;
InternetCloseHandle(hFile);
CloseFile(LocalFile);
Result := True;
end;


procedure TForm1.BitBtn1Click(Sender: TObject);
var
hNet, hFTP: HINTERNET;
strHost,strUser,strPwd,ftpDir: string;
port :Integer;
bSuccess: Boolean;

begin

{ Open an internet session }
hNet := InternetOpen('Program_Name', // Agent
INTERNET_OPEN_TYPE_PRECONFIG, // AccessType
nil, // ProxyName
nil, // ProxyBypass
0); // or INTERNET_FLAG_ASYNC / INTERNET_FLAG_OFFLINE

{
Agent contains the name of the application or
entity calling the Internet functions
}


{ See if connection handle is valid }
if hNet = nil then
begin
ShowMessage('Unable to get access to WinInet.Dll');
Exit;
end;

{ Connect to the FTP Server }
strhost :='192.168.1.1';
strUser :='user';
strPwd :='passwd';
ftpDir :='tmp';
port :=21;
hFTP := InternetConnect(hNet, // Handle from InternetOpen
PChar(strHost), // FTP server
port, // (INTERNET_DEFAULT_FTP_PORT),
PChar(StrUser), // username
PChar(strPwd), // password
INTERNET_SERVICE_FTP, // FTP, HTTP, or Gopher?
0, // flag: 0 or INTERNET_FLAG_PASSIVE
0);// User defined number for callback

if hFTP = nil then
begin
InternetCloseHandle(hNet);
ShowMessage(Format('Host "%s" is not available',[strHost]));
Exit;
end;

{ Change directory }
bSuccess := FtpSetCurrentDirectory(hFTP, PChar(ftpDir));

if not bSuccess then
begin
InternetCloseHandle(hFTP);
InternetCloseHandle(hNet);
ShowMessage(Format('Cannot set directory to %s.',[ftpDir]));
Exit;
end;
FtpDownloadFile(hNet,hFtp,'file1','file1',ProgressBar1);
FtpDownloadFile(hNet,hFtp,'file2','file2',ProgressBar1);
FtpDownloadFile(hNet,hFtp,'file3','file3',ProgressBar1);
InternetCloseHandle(hFTP);
InternetCloseHandle(hNet);
end;
end.
 
谁帮我解决了这个问题不付积分的是小狗
 
OK!
问题解决!

原来是
这里需要注意的关键函数是ftpFindFirstFile, InternetFindNextFile &
InternetCloseHandle。您可以像调用Delphi函数FindFirst、FindNext & FinClose一样调用这些函数。特别的是,您使用函数ftpFindFirstFile来取得这个路径下的第一个函数。您可以不断地调用InternetFindNextFile,直到函数返回"False"为止。当这个进程结束时,调用InternetCloseHandle来通知操作系统回收与这个进程相关的内存。
 
版主能不能把这个问题结束了?
 
可怜的黄葫芦[:D]

你贴的代码太长了,难怪难得有人看了。
 
顶部