【问题标题】:DecodeToStream in Indy10Indy10 中的 DecodeToStream
【发布时间】:2011-01-02 22:46:46
【问题描述】:

我想使用 Delphi 2007 将我的应用程序从 Indy 9 升级到 10。 现在这不再编译了,因为没有找到 DecodeToStream。 代码使用 Bold 框架,因为有对 BoldElement 的引用。

还有其他调用方法吗?

更新(我觉得我把前面的例子简化得太多了)

原码:

    BlobStreamStr  : String;
    MIMEDecoder    : TidDecoderMIME; 

    if (BoldElement is TBATypedBlob) then
    begin
      BlobStreamStr := copy(ChangeValue,pos(']',ChangeValue)+1,maxint);
      (BoldElement as TBATypedBlob).ContentType := copy(ChangeValue,2,pos(']',ChangeValue)-2);

      MIMEDecoder := TidDecoderMIME.Create(nil);
      try
        MIMEDecoder.DecodeToStream(BlobStreamStr,(BoldElement as TBATypedBlob).CreateBlobStream(bmWrite));
      finally
        FreeAndNil(MIMEDecoder);
      end;
    end

更改后:

    BlobStreamStr  : String;
    MIMEDecoder    : TidDecoderMIME; 
    LStream        : TIdMemoryStream;

    if (BoldElement is TBATypedBlob) then
    begin
      BlobStreamStr := copy(ChangeValue, pos(']', ChangeValue) + 1, maxint);
      (BoldElement as TBATypedBlob).ContentType := copy(ChangeValue, 2, pos(']',ChangeValue)-2);

      MIMEDecoder := TidDecoderMIME.Create(nil);
      LStream := TIdMemoryStream.Create;
      try
        MIMEDecoder.DecodeBegin(LStream);
        MIMEDecoder.Decode(BlobStreamStr, 0, Length(BlobStreamStr));
        LStream.Position := 0;
        ReadTIdBytesFromStream(LStream, DecodedBytes, Length(BlobStreamStr));

        // Should memory for this stream be released ??
        (BoldElement as TBATypedBlob).CreateBlobStream(bmWrite).Write(DecodedBytes[0], Length(DecodedBytes));
      finally
        MIMEDecoder.DecodeEnd;
        FreeAndNil(LStream);
        FreeAndNil(MIMEDecoder);
      end;
    end

但我对自己的所有变化都没有信心,因为我对 Indy 了解不多。所以欢迎所有的cmets。我不明白的一件事是对 CreateBlobStream 的调用。我应该与 FastMM 核对一下,这样它就不是内存泄漏了。

【问题讨论】:

  • 是的,对 CreateBlobStream() 的调用是内存泄漏。使用完毕后,您需要 Free() 流。

标签: delphi mime indy


【解决方案1】:

使用 TIdDecoder.DecodeBegin() 是解码为 TStream 的正确方法。但是,您不需要中间 TIdMemoryStream(顺便说一句,它在 Indy 10 中已经存在很长时间了 - 考虑升级到更新的版本)。您可以直接传递 Blob 流,例如:

var
  BlobElement    : TBATypedBlob;
  BlobStreamStr  : String; 
  BlobStream     : TStream;
  MIMEDecoder    : TidDecoderMIME;  
begin 
  ...
  if BoldElement is TBATypedBlob then 
  begin 
    BlobElement := BoldElement as TBATypedBlob;

    BlobStreamStr := Copy(ChangeValue, Pos(']',ChangeValue)+1, Maxint); 
    BlobElement.ContentType := Copy(ChangeValue, 2, Pos(']',ChangeValue)-2); 

    BlobStream := BlobElement.CreateBlobStream(bmWrite);
    try
      MIMEDecoder := TidDecoderMIME.Create(nil); 
      try 
        MIMEDecoder.DecodeBegin(BlobStream);
        try
          MIMEDecoder.Decode(BlobStreamStr); 
        finally
          MIMEDecoder.DecodeEnd;
        end;
      finally 
        FreeAndNil(MIMEDecoder); 
      end; 
    finally
      FreeAndNil(BlobStream);
    end;
  end;
  ...
end;

【讨论】:

  • 我真的希望有像变量这样的本地“接口”。他们会带走这么多样板。例如,BlobStream 会在超出范围时自行释放
  • 感谢示例,现在可以编译了,但我还没有验证结果。这可能属于另一个线程,但代码中最终嵌套了 3 个。这是常见的吗?大量 try/finally 代码会不会出现性能问题?
【解决方案2】:

是的,他们在 9 点到 10 点之间发生了很大变化。

我认为现在您有了“DecodeBytes”而不是 DecodeToStream。所以应该这样做:

var
  DecodedBytes: TIdBytes;
begin
  MIMEDecoder := TidDecoderMIME.Create(nil);
  try
    DecodedBytes := MIMEDecoder.DecodeBytes(vString);
    vStream.Write(DecodedBytes[0], Length(DecodedBytes));
  finally
    FreeAndNil(MIMEDecoder);
  end;
end;

【讨论】:

  • 我没有找到 DecodeBytes 方法,但答案给了我灵感来更改代码,以便获得积分 :)
  • 啊,好吧,现在你的例子有点不同是的。好吧,因为 Remy 是 Indy 的作者之一,我认为听他的话是明智的;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-15
相关资源
最近更新 更多