向各位高手请教一个关于Indy控件的问题(200分)

  • 主题发起人 主题发起人 xda
  • 开始时间 开始时间
X

xda

Unregistered / Unconfirmed
GUEST, unregistred user!
我在用IdMessage控件的LoadFromFile方法和LoadFromStream方法分别从一个文件和流中读取电子邮件的信息时为什么出现错误?(提示为Read Timeout)
 
把调用LoadFromFile和LoadFromStream的程序段贴出来,这样说也不知道什么地方超时了
 
从流中加载电子邮件信息:
Var
BlobStream:TBlobStream;
MemoryStream:TMemoryStream;
begin
BlobStream:=TBlobStream.Create(DataModule2.Table1F5,bmRead); //数据库中的Blob字段,存放电子邮件信息
MemoryStream:=TMemoryStream.Create;
MemoryStream.LoadFromStream(BlobStream);
IdMessage1.LoadFromStream(MemoryStream);
BlobStream.Free;
MemoryStream.Free;
end;
从文件中加载电子邮件信息:
If OpenDialog1.Execute Then
IdMessage1.LoadFromFile(OpenDialog1.FileName);
 
你用的是哪个版本的indy,我用的delphi6自带的,怎么没有
load fromfile和loadfromstream方法?
 
To coolbaby:我用的是delphi7自带的。
 
有timeout属性吗?
找找,设置一下
 
To SuperSoft:没有timeout属性。
 
下面是Indy控件中有关的原代码,请各位高手帮忙分析一下,看有没有修改的可能。
procedure TIdMessage.LoadFromFile(const AFileName: string; const AHeadersOnly: Boolean = False);
var
vStream: TFileStream;
begin
if (not FileExists(AFilename)) then
begin
raise EIdMessageCannotLoad.CreateFmt(RSIdMessageCannotLoad, [AFilename]);
end;

vStream := TFileStream.Create(AFilename, fmOpenRead and fmShareDenyWrite);
try
LoadFromStream(vStream, AHeadersOnly);
finally
vStream.Free;
end;
end;

procedure TIdMessage.LoadFromStream(AStream: TStream; const AHeadersOnly: Boolean = False);
var
vMsgClient : TIdMessageClient;
begin
// clear message properties, headers before loading
Clear;
vMsgClient := TIdMessageClient.Create(nil);
try
vMsgClient.ProcessMessage(Self, AStream, AHeadersOnly);
finally
FreeAndNil(vMsgClient);
end;
end;

procedure TIdMessageclient.ProcessMessage(AMsg: TIdMessage; AHeaderOnly: Boolean = False);
begin
if IOHandler <> nil then
begin
ReceiveHeader(AMsg);
if (not AHeaderOnly) then
begin
ReceiveBody(AMsg);
end;
end;
end;


function TIdMessageClient.ReceiveHeader(AMsg: TIdMessage; const AAltTerm: string = ''): string;
begin
BeginWork(wmRead); try
repeat
Result := ReadLn;
// Exchange Bug: Exchange sometimes returns . when getting a message instead of
// '' then a . - That is there is no seperation between the header and the message for an
// empty message.
if ((Length(AAltTerm) = 0) and (Result = '.')) or
({APR: why? (Length(AAltTerm) > 0) and }(Result = AAltTerm)) then begin
Break;
end else if Result <> '' then begin
AMsg.Headers.Append(Result);
end;
until False;
AMsg.ProcessHeaders;
finally EndWork(wmRead); end;
end;

procedure TIdMessageClient.ReceiveBody(AMsg: TIdMessage; const ADelim: string = '.');
var
LMsgEnd: Boolean;
LActiveDecoder: TIdMessageDecoder;
LLine: string;

function ProcessTextPart(ADecoder: TIdMessageDecoder): TIdMessageDecoder;
var
LDestStream: TStringStream;
begin
LDestStream := TStringStream.Create('');
try
Result := ADecoder.ReadBody(LDestStream, LMsgEnd);
with TIdText.Create(AMsg.MessageParts) do
begin
ContentType := ADecoder.Headers.Values['Content-Type'];
ContentTransfer := ADecoder.Headers.Values['Content-Transfer-Encoding'];
Body.Text := LDestStream.DataString;
end;
ADecoder.Free;
finally
FreeAndNil(LDestStream);
end;
end;

function ProcessAttachment(ADecoder: TIdMessageDecoder): TIdMessageDecoder;
var
LDestStream: TFileStream;
LTempPathname: string;
begin
LTempPathname := MakeTempFilename;
LDestStream := TFileStream.Create(LTempPathname, fmCreate);
try
Result := ADecoder.ReadBody(LDestStream, LMsgEnd);
with TIdAttachment.Create(AMsg.MessageParts) do
begin
ContentType := ADecoder.Headers.Values['Content-Type'];
ContentTransfer := ADecoder.Headers.Values['Content-Transfer-Encoding'];

// dsiders 2001.12.01
ContentDisposition := ADecoder.Headers.Values['Content-Disposition'];

Filename := ADecoder.Filename;
StoredPathname := LTempPathname;
end;
ADecoder.Free;
finally
FreeAndNil(LDestStream);
end;
end;

const
wDoublePoint = ord('.') shl 8 + ord('.');

Begin
LMsgEnd := False;
if AMsg.NoDecode then
begin
Capture(AMsg.Body, ADelim);
end

else begin
BeginWork(wmRead);
try
LActiveDecoder := nil;
repeat
LLine := ReadLn;
if LLine = ADelim then
begin
Break;
end;
if LActiveDecoder = nil then
begin
LActiveDecoder := TIdMessageDecoderList.CheckForStart(AMsg, LLine);
end;
if LActiveDecoder = nil then begin
if PWord(PChar(LLine))^= wDoublePoint then begin
Delete(LLine,1,1);
end;//if '..'
AMsg.Body.Add(LLine);
end else begin
while LActiveDecoder <> nil do begin
LActiveDecoder.SourceStream := TIdTCPStream.Create(Self);
LActiveDecoder.ReadHeader;

case LActiveDecoder.PartType of
mcptUnknown:
begin
raise EIdException.Create(RSMsgClientUnkownMessagePartType);
end;

mcptText:
begin
LActiveDecoder := ProcessTextPart(LActiveDecoder);
end;

mcptAttachment:
begin
LActiveDecoder := ProcessAttachment(LActiveDecoder);
end;
end;
end;
end;
until LMsgEnd;
finally
EndWork(wmRead);
end;
end;
end;

IdPop3的Retrieve函数源代码如下,从中可以看出它也用到了ReceiveBody方法和ReceiveHeader方法。但用IdMessage控件和IdPop3控件接收邮件没有问题。这是怎么回事呢?

function TIdPOP3.Retrieve(const MsgNum: Integer; AMsg: TIdMessage): Boolean;
begin
if SendCmd('RETR ' + IntToStr(MsgNum)) = wsOk then {Do not Localize}
begin
// This is because of a bug in Exchange? with empty messages. See comment in ReceiveHeader
if Length(ReceiveHeader(AMsg)) = 0 then begin
// Only retreive the body if we do not already have a full RFC
ReceiveBody(AMsg);
end;
end;
// Will only hit here if ok and NO exception, or IF is not executed
Result := LastCmdResult.NumericCode = wsOk;
end;
 
哪位大侠有CSDN上的《Indy问题集》的文档,如能提供另加100分。
 
http://www.nevrona.com/Indy/FAQ.html有下
英文的
 
Indy的FAQ中在讲到LoadFromFile出现EIdReadTimeout时,有这样一段话:
"Your message files need to be properly terminated for the Indy LoadFromFile and LoadFromStream methods. You must terminate the message with a "<CR><LF>.<CR><LF>". The Indy helpfile notes this behavior by indicating"
那么我具体该怎么做呢?
 
Indy 帮助文件,告诉你:
你的message文件必须用一个<CR><LF>结尾。
也就是所谓的回车<CR>换行<LF>符号呀[:D]
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部