Das ist ein Auszug aus IdIOHandler vom letzen Snapshot von
Indy 10.
Wie man sieht ist dort das buffering auskommentiert.
Herbert hat das ja auf andere Weise gelöst.
Delphi-Quellcode:
procedure TIdIOHandler.
Write(AStream: TIdStream; ASize: Int64 = 0;
AWriteByteCount: Boolean = FALSE);
var
LBuffer: TIdBytes;
LBufSize: Integer;
// LBufferingStarted: Boolean;
begin
if ASize < 0
then begin //"-1" All form current position
LBufSize := AStream.Position;
ASize := AStream.Size;
//todo1 is this step required?
AStream.Position := LBufSize;
ASize := ASize - LBufSize;
end
else if ASize = 0
then begin //"0" ALL
ASize := AStream.Size;
AStream.Position := 0;
end;
//else ">0" ACount bytes
EIdIOHandlerRequiresLargeStream.IfTrue((ASize > High(Integer))
and (
not LargeStream));
// RLebeau 3/19/2006: DO NOT ENABLE WRITE BUFFERING IN THIS METHOD!
//
// When sending large streams, especially with LargeStream enabled,
// this can easily cause "Out of Memory" errors. It is the caller's
// responsibility to enable/disable write buffering as needed before
// calling one of the Write() methods.
//
// Also, forcing write buffering in this method is having major
// impacts on TIdFTP, TIdFTPServer, and TIdHTTPServer.
{
LBufferingStarted := not WriteBufferingActive;
LBufferingStarted := False;
if LBufferingStarted then begin
WriteBufferOpen;
end;
}
//try
if AWriteByteCount
then begin
if LargeStream
then begin
Write(ASize);
end else begin
Write(Integer(ASize));
end;
end;
BeginWork(wmWrite, ASize);
try
while ASize > 0
do begin
SetLength(LBuffer, FSendBufferSize);
//BGO: bad for speed
LBufSize := Min(ASize, FSendBufferSize);
// Do not use ReadBuffer. Some source streams are real time and will not
// return as much data as we request. Kind of like recv()
// NOTE: We use .Size - size must be supported even if real time
LBufSize := TIdStreamHelper.ReadBytes(AStream, LBuffer, LBufSize);
if LBufSize = 0
then begin
raise EIdNoDataToRead.Create(RSIdNoDataToRead);
end;
SetLength(LBuffer, LBufSize);
Write(LBuffer);
// RLebeau: DoWork() is called in TIdIOHandlerStack.WriteDirect() <---------------
//DoWork(wmWrite, LBufSize); <--- vielleicht wenn es nicht laufen sollte, hier doWork wieder aktivieren.
Dec(ASize, LBufSize);
end;
finally
EndWork(wmWrite);
LBuffer :=
nil;
end;
{
if LBufferingStarted then begin
WriteBufferClose;
end;
except
if LBufferingStarted then begin
WriteBufferCancel;
end;
raise;
end;
}
end;
Nun der Auszug aus idIOHandlerStack:
Delphi-Quellcode:
procedure TIdIOHandlerStack.WriteDirect(var ABuffer: TIdBytes);
var
LCount: Integer;
LPos: Integer;
LSize: Integer;
begin
inherited WriteDirect(ABuffer);
Assert(Binding<>nil);
LSize := Length(ABuffer);
LPos := 0;
repeat
LCount := Binding.Send(ABuffer, LPos, LSize - LPos);
// TODO - Have a AntiFreeze param which allows the send to be split up so that process
// can be called more. Maybe a prop of the connection, MaxSendSize?
TIdAntiFreezeBase.DoProcess(False);
FClosedGracefully := LCount = 0;
// Check if other side disconnected
CheckForDisconnect;
DoWork(wmWrite, LCount);
Inc(LPos, LCount);
until LPos >= LSize;
end;
Wo der aufgerufen wird ist mir aber nicht ersichtlich.
Grüße
Klaus