Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi InternetSetFilePointer, InternetReadFile & Download fortsetz (https://www.delphipraxis.net/66894-internetsetfilepointer-internetreadfile-download-fortsetz.html)

Harry M. 6. Apr 2006 06:53


InternetSetFilePointer, InternetReadFile & Download fort
 
Ich will mit InternetSetFilePointer und InternetReadFile einen unterbrochenen FTP-Download wieder aufnehemen.
Dabei tritt jenes Problem auf, das der Download nicht fortgesetzt, sondern neu gestartet wird und genau das will ich ja eben nicht...

Delphi-Quellcode:
function FtpDownloadFile(strHost, strUser, strPwd: string;
  Port: Integer; ftpDir, ftpFile, TargetFile: string; ProgressBar: TProgressBar): Boolean;

  function FmtFileSize(Size: Integer): string;
  begin
    if Size >= $F4240 then
      Result := Format('%.2f', [Size / $F4240]) + ' Mb'
    else
    if Size < 1000 then
      Result := IntToStr(Size) + ' bytes'
    else
      Result := Format('%.2f', [Size / 1000]) + ' Kb';
  end;

  function GetFileSize(Filename: String): Cardinal;
  var
    fs : TFilestream;
  begin
    fs := TFileStream.Create(Filename, fmOpenRead + fmShareDenyNone);
    Result := fs.Size;
    fs.Free
  end;

const
  READ_BUFFERSIZE = 256; // or 256, 512, ...
var
  hNet, hFTP, hFile: HINTERNET;
  buffer: array[0..READ_BUFFERSIZE - 1] of Char;
  bufsize, dwBytesRead, fileSize: DWORD;
  sRec: TWin32FindData;
  strStatus: string;
  LocalFile: file;
  bSuccess: Boolean;
  fs: TFileStream;
begin
  Result := False;

  { 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 }
  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;

  { Read size of file }
  if FtpFindFirstFile(hFTP, PChar(ftpFile), sRec, 0, 0) <> nil then
  begin
    fileSize := sRec.nFileSizeLow;
    // fileLastWritetime := sRec.lastWriteTime
  end else
  begin
    InternetCloseHandle(hFTP);
    InternetCloseHandle(hNet);
    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
    InternetCloseHandle(hFTP);
    InternetCloseHandle(hNet);
    Exit;
  end;

  if FileExists(TargetFile) then begin
    fs := TFileStream.Create(TargetFile, fmOpenReadWrite);
    fs.Position := fs.Size;
    dwBytesRead := fs.Size;
    InternetSetFilePointer(hFile, dwBytesRead, nil, FILE_Current, 0); // hier in der Remotefile nach vorne springen
    end else begin
      fs := TFileStream.Create(TargetFile, fmCreate);
      dwBytesRead := 0;
      end;

  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
      fs.WriteBuffer(buffer, bufsize);

    dwBytesRead := dwBytesRead + bufsize;

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

  fs.Free;

  InternetCloseHandle(hFile);
  InternetCloseHandle(hFTP);
  InternetCloseHandle(hNet);
  Result := True;
end;
Sieht den jemand das Problem???

marabu 6. Apr 2006 07:24

Re: InternetSetFilePointer, InternetReadFile & Download
 
Guten Morgen Harry.

Keine Ahnung was da schief läuft. Vielleicht unterstützt der Server kein Resume?

Delphi-Quellcode:
begin
  // ...
  dwBytesSkipped := InternetSetFilePointer(hFile, dwBytesRead, nil, FILE_BEGIN, 0);
  if dwBytesSkipped = -1 
    then Panic()
    else fs.Position := dwBytesSkipped;
  // ...
end;
Grüße vom marabu

Harry M. 6. Apr 2006 07:38

Re: InternetSetFilePointer, InternetReadFile & Download
 
Morgen, Morgen!!
Zitat:

Zitat von marabu
Vielleicht unterstützt der Server kein Resume?

Kann eigendlich nicht sein, Server ist Serv-U und mit SmartFTP kann ich den Download fortsetzten.

Harry M. 6. Apr 2006 09:04

Re: InternetSetFilePointer, InternetReadFile & Download
 
Habe das Problem jetzt mit den Indys ungefähr so behoben:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
const
  myfile = 'Test.avi';
var
  AStream: TFileStream;
begin
  if IdFTP1.Connected then
    IdFTP1.Disconnect;
   
  IdFTP1.Host := '192.168.0.10';
  IdFTP1.Port := 21;
  IdFTP1.Username := 'xxx';
  IdFTP1.Password := 'xxx';

  if FileExists(TargetFile) then begin
    AStream := TFileStream.Create(TargetFile, fmOpenReadWrite);
    AStream.Position := AStream.Size;
    end else
      AStream := TFileStream.Create(TargetFile, fmCreate);

  IdFTP1.Connect(True, -1);

  if IdFTP1.Connected then begin
    ProgressBar1.Max := IdFTP1.Size(myfile);
    IdFTP1.Get(myfile, AStream, True);
    IdFTP1.Disconnect;
    end;

  AStream.Free;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:14 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz