Delphi - 需要Delphi7的XE2代码.使用wininet下载文件

Jos*_*ine 1 delphi wininet download delphi-7 code-conversion

注意:我只想使用wininet,而不是urlmon-urldownloadtofile.

好吧,我有以下代码在XE2中完美地下载文件:

procedure DownloadFile(URL: string; Path: string);
const
  BLOCK_SIZE = 1024;
var
  InetHandle: Pointer;
  URLHandle: Pointer;
  FileHandle: Cardinal;
  BytesRead: Cardinal;
  DownloadBuffer: Pointer;
  Buffer: array [1 .. BLOCK_SIZE] of byte;
  BytesWritten: Cardinal;
begin
  InetHandle := InternetOpen(PWideChar(URL), 0, 0, 0, 0);
  URLHandle := InternetOpenUrl(InetHandle, PWideChar(URL), 0, 0, 0, 0);
  FileHandle := CreateFile(PWideChar(Path), GENERIC_WRITE, FILE_SHARE_WRITE, 0,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
  DownloadBuffer := @Buffer;
  repeat
    InternetReadFile(URLHandle, DownloadBuffer, BLOCK_SIZE, BytesRead);
    if not WriteFile(FileHandle, DownloadBuffer, BytesRead, BytesWritten, 0) or
  (BytesWritten <> BytesRead) then
      RaiseLastOSError;
  until BytesRead < BLOCK_SIZE;
  CloseHandle(FileHandle);
  InternetCloseHandle(URLHandle);
  InternetCloseHandle(InetHandle);
end;
Run Code Online (Sandbox Code Playgroud)

以上代码的学分转到了jachguate.他编辑了我的代码来纠正它,我为此感谢他.

现在,此代码仅在Delphi XE2下正常运行.我尝试在Delphi 7下使用它并且它无法正常工作.它似乎在一段时间内将相同的"行"或"字节序列"存储到文件中.

以下是我在Delphi 7中使用的上述代码的两个重组 - 两者都没有正常工作.

procedure DownloadFile(URL: string; Path: string);
const
  BLOCK_SIZE = 1024;
var
  InetHandle: Pointer;
  URLHandle: Pointer;
  FileHandle: Cardinal;
  BytesRead: Cardinal;
  DownloadBuffer: Pointer;
  Buffer: array [1 .. BLOCK_SIZE] of byte;
  BytesWritten: Cardinal;
begin
  InetHandle := InternetOpen(PChar(URL), 0, 0, 0, 0);
  URLHandle := InternetOpenUrl(InetHandle, PChar(URL), 0, 0, 0, 0);
  FileHandle := CreateFile(PChar(Path), GENERIC_WRITE, FILE_SHARE_WRITE, 0,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
  DownloadBuffer := @Buffer;
  repeat
    InternetReadFile(URLHandle, DownloadBuffer, BLOCK_SIZE, BytesRead);
    if not WriteFile(FileHandle, DownloadBuffer, BytesRead, BytesWritten, 0) or
  (BytesWritten <> BytesRead) then
      RaiseLastOSError;
  until BytesRead < BLOCK_SIZE;
  CloseHandle(FileHandle);
  InternetCloseHandle(URLHandle);
  InternetCloseHandle(InetHandle);
end;
Run Code Online (Sandbox Code Playgroud)
procedure DownloadFile(URL: string; Path: string);
const
  BLOCK_SIZE = 1024;
var
  InetHandle: Pointer;
  URLHandle: Pointer;
  FileHandle: Cardinal;
  BytesRead: Cardinal;
  DownloadBuffer: Pointer;
  Buffer: array [1 .. BLOCK_SIZE] of byte;
  BytesWritten: Cardinal;
begin
  InetHandle := InternetOpen(PAnsiChar(URL), 0, 0, 0, 0);
  URLHandle := InternetOpenUrl(InetHandle, PAnsiChar(URL), 0, 0, 0, 0);
  FileHandle := CreateFile(PAnsiChar(Path), GENERIC_WRITE, FILE_SHARE_WRITE, 0,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
  DownloadBuffer := @Buffer;
  repeat
    InternetReadFile(URLHandle, DownloadBuffer, BLOCK_SIZE, BytesRead);
    if not WriteFile(FileHandle, DownloadBuffer, BytesRead, BytesWritten, 0) or
  (BytesWritten <> BytesRead) then
      RaiseLastOSError;
  until BytesRead < BLOCK_SIZE;
  CloseHandle(FileHandle);
  InternetCloseHandle(URLHandle);
  InternetCloseHandle(InetHandle);
end;
Run Code Online (Sandbox Code Playgroud)

只编辑过的是数据类型转换.使用实施例1"PChar",并使用实施例2"PAnsiChar".

RRU*_*RUZ 5

你在文件中得到垃圾,因为你需要DownloadBuffer使用 ^char 取消引用指针,所以要修复你的方法只需替换这段代码

WriteFile(FileHandle, DownloadBuffer, BytesRead, BytesWritten, 0)
Run Code Online (Sandbox Code Playgroud)

这样

WriteFile(FileHandle, DownloadBuffer^, BytesRead, BytesWritten, 0)
Run Code Online (Sandbox Code Playgroud)

顺便说一句,记得在你的函数中添加try..finally块以确保在发生异常时释放句柄.