indy10的idHttpServer发送流
先看源码:
procedure TIdIOHandler.Write(AStream: TStream; ASize: TIdStreamSize = 0;
AWriteByteCount: Boolean = FALSE);
var
LBuffer: TIdBytes;
LStreamPos: TIdStreamSize;
LBufSize: Integer;
// LBufferingStarted: Boolean;
begin
if ASize < 0 then begin //"-1" All from current position
LStreamPos := AStream.Position;
ASize := AStream.Size - LStreamPos;
AStream.Position := LStreamPos;
end
else if ASize = 0 then begin //"0" ALL
ASize := AStream.Size;
AStream.Position := 0;
end;
//else ">0" number of bytes
// 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.
if AWriteByteCount then begin
if LargeStream then begin
Write(Int64(ASize));
end else begin
{$IFDEF STREAM_SIZE_64}
if ASize > High(Integer) then begin
raise EIdIOHandlerRequiresLargeStream.Create(RSRequiresLargeStream);
end;
{$ENDIF}
Write(Int32(ASize));
end;
end;
BeginWork(wmWrite, ASize);
try
SetLength(LBuffer, FSendBufferSize);
while ASize > 0 do begin
LBufSize := IndyMin(ASize, Length(LBuffer));
// 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;
Write(LBuffer, LBufSize);
// RLebeau: DoWork() is called in WriteDirect()
//DoWork(wmWrite, LBufSize);
Dec(ASize, LBufSize);
end;
finally
EndWork(wmWrite);
LBuffer := nil;
end;
end;
const
GRecvBufferSizeDefault = 32 * 1024;
GSendBufferSizeDefault = 32 * 1024;
如果流数据大于32K,会分成多包发送,每包最大32K。