You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让TDownloadURL.DownloadRawBytes在无ContentType头时跳过字符串转换?

问题描述

尝试使用Rest.Client单元中的TDownloadURL.DownloadRawBytes从Amazon S3存储桶下载PDF文件,遇到以下问题:

  • 服务器返回的ContentType为空,且无法控制服务器端设置正确的ContentType
  • TRESTRequest.Execute会因ContentType为空,强制将MimeKind设为TMimeTypes.TKind.Text,导致返回的字节被强制转换为字符串
  • 执行请求时抛出异常:

Project raised exception class EEncodingError with message 'No mapping for the Unicode character exists in the target multi-byte code page'.

疑问:

  1. 是否有其他更合适的方法可以使用?
  2. 是否遗漏了强制二进制模式或跳过字符串转换的方式?
  3. 是否存在不会失败的TEncoding选项?曾寻找可编码所有内容的十六进制编码,但未找到。

解决方案

1. 使用更直接的HTTP客户端方法

绕过TDownloadURL,改用Delphi自带的THTTPClient(XE8及以上版本支持)处理二进制下载,它不会因ContentType为空触发字符串转换逻辑:

var
  HttpClient: THTTPClient;
  ResponseStream: TMemoryStream;
begin
  HttpClient := THTTPClient.Create;
  ResponseStream := TMemoryStream.Create;
  try
    HttpClient.Get('你的S3文件URL', ResponseStream);
    // 保存或处理二进制流
    ResponseStream.SaveToFile('downloaded.pdf');
  finally
    ResponseStream.Free;
    HttpClient.Free;
  end;
end;

THTTPClient默认以二进制模式处理响应,直接保留原始字节,完全适配PDF这类二进制文件。

2. 强制Rest.Client以二进制模式处理响应

如果必须使用Rest.Client组件,可通过以下方式绕过字符串转换:

  • 执行请求前手动设置TRESTResponse的ContentType为通用二进制类型:
RESTResponse1.ContentType := 'application/octet-stream';
RESTRequest1.Execute;
// 直接读取RawBytes属性,避免触发字符串转换
var RawBytes: TBytes;
RawBytes := RESTResponse1.RawBytes;
TFile.WriteAllBytes('downloaded.pdf', RawBytes);

注意:必须读取RawBytes而非Content属性,Content会触发内部编码转换逻辑,RawBytes直接保留服务器返回的原始字节。

  • 也可通过OnResponseReceived事件提前干预响应类型:
procedure TForm1.RESTRequest1ResponseReceived(Sender: TCustomRESTRequest;
  Response: TCustomRESTResponse);
begin
  Response.ContentType := 'application/octet-stream';
end;

3. 关于无失败的编码选项

不存在能完美编码任意二进制字节的TEncoding——文本编码是为字符设计的,二进制数据中的非字符字节会破坏编码规则,必然触发异常。

你提到的十六进制编码不属于TEncoding范畴,可通过TNetEncoding.Hex实现字节与十六进制字符串的互转,但会额外增加数据体积,不如直接操作字节流高效。若非要用字符串中转,Base64编码(TNetEncoding.Base64)是更通用的选择,但同样属于额外处理,远不如直接操作二进制流便捷。


内容的提问来源于stack exchange,提问作者Mark Elder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 04:52:11