TIdAttachment-获取附件的正确文件名-没有utf-8编码信息

问题描述 投票:0回答:1

在我的项目中,我尝试从.eml文件中提取附件。

在正常条件下(字符集ISO),它可以工作。但是在特殊情况下,它为附件提供了错误的文件名。

这是我的示例中的MessagePart的外观:

------=_Part_315_1401515384.1585891801067
Content-Type: application/octet-stream; 
    name="=?UTF-8?Q?Report=5F2020-3=5FCustomerA.csv?="
Content-Transfer-Encoding: base64
Content-Disposition: attachment; 
    filename="=?UTF-8?Q?Report=5F2020-3=5FCustomerA.csv?="

UGFydG5lcjtNYW5kYW50ZW5uYW1lO05hbWU7RmlybWE7U3RyYd9lO1Bvc3RsZWl0emFobDtPcnQ7
TGFuZDtQcm9kdWt0bGluaWU7S3VuZGVuc3RhdHVzO0RhdHVtIFJlZ2lzdHJpZXJ1bmc7QmVnaW5u
IEthdWY7S/xuZGlndW5nIGf8bHRpZyBhYjtBbnphaGwgQmVudXR6ZXI7QW56YWhsIE1vYmlsZSBz
eW5jO05ldHRvIFJlY2hudW5nc2JldHJhZyBpbiBFdXJvO1Byb3Zpc2lvbnNzdHVmZTtQcm92aXNp
b25zYW50ZWlsIGluIEV1cm8NCg==
------=_Part_315_1401515384.1585891801067--

到目前为止没有什么特别的。但是由于某种原因,我没有从该附件中获得正确的文件名。

这是我的代码,用于获取该文件的文件名并将其保存到临时位置:

function foo(MyMail: TIdMessage; SavePathWithoutBackSlash : string): boolean;
var
 i : Integer;
 lfilename: string;
begin
  for i := 0 to Pred(MyMail.MessageParts.Count) do
    begin
      if (MyMail.MessageParts.Items[i] is TIdAttachmentFile) then
      begin
        lFilename := TIdAttachmentFile(MyMail.MessageParts.Items[i]).FileName;
        TIdAttachmentFile(MyMail.MessageParts.Items[i]).SaveToFile(SavePathWithoutBackSlash + '\' + lFilename);
      end;
    end;
  end; 
end;

我已经尝试了很多编码,但是似乎没有影响。

我期望的是类似path/Report_2020-3_CustomerA.csv的字符串

我得到的是:path/=?UTF-8?Q?Report=5F2020-3=5FCustomerA.csv?=

如何正确保存附件?

delphi utf-8 email-attachments indy mime
1个回答
1
投票

向@olivier致谢,我找到了该问题的解决方案。它是2个问题的组合。

第一个问题:

TIdAttachmentFile(MyMail.MessageParts.Items[i]).FileName

不返回=?UTF-8?Q?它返回= _UTF-8_Q_所以我将其更改为

TIdAttachmentFile(MyMail.MessageParts.Items[i]).Name

-

第二个问题:

根据RFC2047的=?...?=之间不允许有空格。因此DecodeHeader将保持字符串不变。我的代码现在可以正常工作,如下所示:

Uses 
  ...IdAttachmentFile, IdMessage, IdCoderHeader...  

function foo(MyMail: TIdMessage; SavePathWithoutBackSlash : string): boolean;
    var
     i : Integer;
     lfilename: string;
    begin
      for i := 0 to Pred(MyMail.MessageParts.Count) do
        begin
          if (MyMail.MessageParts.Items[i] is TIdAttachmentFile) then
          begin
            lFilename := TIdAttachmentFile(MyMail.MessageParts.Items[i]).Name;
            if pos('=?UTF-8?Q?',uppercase(lfilename)) > 0 then
            begin
              lfilename:=StringReplace(lFilename,' ','=20',[rfReplaceAll,rfIgnoreCase]);
            end;
            lFileName:= DecodeHeader(lFileName);
            TIdAttachmentFile(MyMail.MessageParts.Items[i]).SaveToFile(SavePathWithoutBackSlash + '\' + lFilename);
          end;
        end;
      end; 
    end;

= 20是带引号可打印的UTF-8中空白的正确符号

© www.soinside.com 2019 - 2024. All rights reserved.