在Delphi中,假设InternetCloseHandle()不会失败,这样改写代码以允许更清晰的表述,是否安全且合理?

2026-04-10 02:181阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计541个文字,预计阅读时间需要3分钟。

在Delphi中,假设InternetCloseHandle()不会失败,这样改写代码以允许更清晰的表述,是否安全且合理?

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

c++function Request(const pConnection: HINTERNET; const localpath: string): string;var Buffer: packed Array[1..5000] of Char; BytesRead: Cardinal;begin Result :=''; if InternetReadFile(pConnection, @Buffer, SizeOf(Buffer), BytesRead) then Result :=Copy(Buffer, 1, BytesRead) else raise Exception.Create('Error reading from the server.');end;

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

在Delphi中,假设InternetCloseHandle()不会失败,这样改写代码以允许更清晰的表述,是否安全且合理?

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;

如果即使成功分配了pRequest,InternetCloseHandle(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的任何错误检查.我试图为你写.

本文共计541个文字,预计阅读时间需要3分钟。

在Delphi中,假设InternetCloseHandle()不会失败,这样改写代码以允许更清晰的表述,是否安全且合理?

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

c++function Request(const pConnection: HINTERNET; const localpath: string): string;var Buffer: packed Array[1..5000] of Char; BytesRead: Cardinal;begin Result :=''; if InternetReadFile(pConnection, @Buffer, SizeOf(Buffer), BytesRead) then Result :=Copy(Buffer, 1, BytesRead) else raise Exception.Create('Error reading from the server.');end;

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

在Delphi中,假设InternetCloseHandle()不会失败,这样改写代码以允许更清晰的表述,是否安全且合理?

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;

如果即使成功分配了pRequest,InternetCloseHandle(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的任何错误检查.我试图为你写.