这是使用 WinINet 执行 HTTP 请求并返回获取的字符串或引发异常的例程:

function Request(const pConnection: HINTERNET; const localpath: string): string;
var Buffer: packed Array[1..5000] of Char; BytesRead: Cardinal; pRequest: HINTERNET;     sent: boolean;
begin
Result := '';
pRequest := HTTPOpenRequest(pConnection, 'GET', pchar(localpath), nil, nil, nil, 0, 0);
if pRequest <> nil then
  begin
  sent := HTTPSendRequest(pRequest, nil, 0, nil, 0);
  if sent then
    while InternetReadFile(pRequest, @Buffer, SizeOf(Buffer)-1 {leave room for terminator}, BytesRead) do
      begin
      Buffer[BytesRead+1] := #0;
      Result := Result + buffer;
      end;
  InternetCloseHandle(pRequest);
  if not sent then RaiseLastOSerror; // HTTPSendRequest failed
  end
else RaiseLastOSerror; // HTTPOpenRequest failed
end;

如果 InternetCloseHandle(pRequest) 失败,即使 pRequest 已成功分配,GetLastError() 将返回 InternetCloseHandle() 而不是 HTTPSendRequest() 的错误代码。修复这将需要如下代码:
function Request(const pConnection: HINTERNET; const localpath: string): string;
var Buffer: packed Array[1..5000] of Char; BytesRead: Cardinal; pRequest: HINTERNET;
begin
Result := '';
pRequest := HTTPOpenRequest(pConnection, 'GET', pchar(localpath), nil, nil, nil, 0, 0);
if pRequest <> nil then
  begin
  if HTTPSendRequest(pRequest, nil, 0, nil, 0) then
    while InternetReadFile(pRequest, @Buffer, SizeOf(Buffer)-1 {leave room for terminator}, BytesRead) do
      begin
      Buffer[BytesRead+1] := #0;
      Result := Result + buffer;
      end
  else
    begin
    InternetCloseHandle(pRequest);
    RaiseLastOSerror; // HTTPSendRequest failed
    end;
  InternetCloseHandle(pRequest);
  end
else RaiseLastOSerror; // HTTPOpenRequest failed
end;

但这乍一看似乎更丑陋,更令人困惑。

假设 InternetCloseHandle() 不会失败从而允许更简单的代码是否安全?

最佳答案

我认为你这样做是错误的。您应该简单地检查每个 API 调用中的错误,并在遇到异常时立即引发异常。这样,您将获得适合产生异常的错误的错误消息。您不能指望继续调用其他 API 函数,然后针对前段时间发生的错误引发异常。

我想你想要这样的东西:

Result := '';
pRequest := HTTPOpenRequest(pConnection, 'GET', pchar(localpath), nil, nil, nil, 0, 0);
if pRequest=nil then
  RaiseLastOSerror;
try
  CheckWin32Error(HTTPSendRequest(pRequest, nil, 0, nil, 0));
  while InternetReadFile(pRequest, @Buffer, SizeOf(Buffer)-1, BytesRead) do begin
    Buffer[BytesRead+1] := #0;
    Result := Result + buffer;
  end;
  if GetLastError<>0 then
    RaiseLastOSerror;
finally
  CheckWin32Error(InternetCloseHandle(pRequest));
end;

请注意,您没有对 InternetReadFile 进行任何错误检查。我试图为你写它。

关于delphi - 假设 InternetCloseHandle() 不会失败从而允许更清晰的代码是否安全?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6583733/

10-10 09:10