Здравствуйте, пытаюсь с помощью функций WinInet закачать файл на ftp-сервер, делаю это так:
function TWinInetFTP.Put(Source, Dest, FileName: string; CreateFolder: boolean): boolean;
var FileStream: TFileStream;
begin
Result := false;
if FileName = '' then FileName := ExtractFileName(Source);
try
FileStream := TFileStream.Create(Source, fmOpenRead, 0);
try
Result := Put(FileStream, Dest, FileName, CreateFolder)
finally
FileStream.Free
end
except
SetError('Put', 'File stream read error', GetLastError)
end
end;
function TWinInetFTP.Put(Stream: TStream; Dest, FileName: string;
CreateFolder: boolean): boolean;
var
TotalBytesWrite, BytesToWrite, BytesWrite: dword;
buf: array of char;
begin
Result := false;
Terminate := false;
BytesWrite := 0;
TotalBytesWrite := 0;
Stream.Position := 0;
if Dest[1] <> '/' then Dest := '/' + Dest;
if Dest[Length(Dest)] <> '/' then Dest := Dest + '/';
if not SetCurDir(Dest) then
if not CreateFolder then
begin
SetError('Put', 'SetCurDir', GetLastError);
Exit
end
else if not MakeDir(Dest) then Exit;
hFile := FtpOpenFile(hConnect, PChar(FileName), GENERIC_WRITE, 0, 0);
if not Assigned(hFile) then
SetError('Put', 'FtpOpenFile', GetLastError)
else
try
SetLength(buf, BufferSize - 1);
with Stream do
repeat
Application.ProcessMessages;
if Terminate then Exit;
Seek(TotalBytesWrite, soFromBeginning);
BytesToWrite := BufferSize;
if BytesToWrite > Size - Position then BytesToWrite := Size - Position;
ReadBuffer(buf[0], BytesToWrite);
if not InternetWriteFile(hFile, @buf[0], BytesToWrite, BytesWrite)
then
begin
SetError('Put', 'InternetWriteFile', GetLastError);
Break
end;
TotalBytesWrite := TotalBytesWrite + BytesWrite;
if Assigned(FOnTransferEvent) then FOnTransferEvent(Self, Stream.Position)
until Position = Size;
Stream.Position := 0;
Result := true
finally
buf := nil;
MainForm.RichEdit.Lines.Append('Перед InternetCloseHandle');
if not InternetCloseHandle(hFile) then ;
MainForm.RichEdit.Lines.Append('После InternetCloseHandle')
end;
MainForm.RichEdit.Lines.Append('Выход из процедуры \"Put (Stream)\"')
end;
То есть вызываю процедуру Put с именем файла в параметре, которая вызывает второй Put, обёртки для функций WinInet были сделаны для удобства (часто его использую + чтобы было хоть внешне похоже на Indy). Проблема в следующем - в день копируется достаточно много файлов, и примерно один раз на каждые 2000-3000 тысячи файлов программка зависает на вызове InternetCloseHandle (то бишь даже ошибку узнать не могу), в инете нашёл предложение как вариант использовать асинхронные вызовы и устанавливать свой таймаут на выполнение процедуры, но связываться с асинхронными вызовами не хотелось бы тем более что синхронные вполне устраивют кроме непонятного периодического зависания InternetCloseHandle.
Подскажите плиз что ещё можно попробовать и в чём в принципе может быть загвоздка?