PDA

Просмотр полной версии : Delphi [TStream]


Flame of Soul
15.03.2009, 15:47
...# Delphi [TStream] #...

Требуется:
Простите за столь глупую просьбу, но приведите пожалуйста пример передачи содержимого компонента через TStream или TMemoryStream, связка клиент - сервер, Winsock, Socket, IdUdp неважно, и вывод его сразу на аналогичный компонент без сохранения на жестком диске даже в виде временных файлов.

Пояснение:
Просто, какая-то странность, сохраняю содержимое компонента в поток, проверяю размер потока, все нормально, отправляю поток по запросу клиента на сервер, на сервер ничего не приходит. Если сохранять через TFileStream и отправлять через него то все работает, но только это дополнительная нагрузка на систему: записывать на винт --> отсылать --> удалять с винта.

Уточнение:
Пожалуйста приведите пример, компонент может быть любой, но для примера допустим пусть будет содержимое Image.Picture


За ранее большое спасибо.

(PS: просьба без лишних фраз, ответы писать по теме, пожалуйста)

Algol
15.03.2009, 21:42
Приведи пример кода.

Flame of Soul
15.03.2009, 23:46
Простите, ночую у родителей, но вот код для примера, который должен на мой взгляд работать.

Код для сервера:
...
RuSrm: TStream;
...

procedure TForm1.FormCreate(...);
begin
RuSrm:= nil;
end;

procedure TForm1.FormDestroy(...);
begin
if Assigned(ComSrm) then
begin
RuSrm.Free;
RuSrm:= nil;
end;
end;

procedure TForm1.ServerSocket1ClientConnect(...);
begin
RuSrm := TStream.Create;
Image1.Picture.Bitmap.SaveToStream(RuSrm);
Socket.SendStream(RuSrm);
end;

procedure TForm1.btnTestSocketsClick(...);
begin
ServerSocket1.Active := True;
end;

end.

Код для клиента:
...
private
ComSrm: TStream;
...

procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
iLen: Integer;
Bfr: Pointer;
begin
iLen := Socket.ReceiveLength;
GetMem(Bfr, iLen);
try
Socket.ReceiveBuf(Bfr^, iLen);
ComSrm.Write(Bfr^, iLen);
finally
FreeMem(Bfr);
end;
end;

procedure TForm1.FormCreate(...);
begin
ComSrm := nil;
end;

procedure TForm1.FormDestroy(...);
begin
if Assigned(ComSrm) then
begin
ComSrm.Free;
ComSrm := nil;
end;
end;

procedure TForm1.ClientSocket1Disconnect(...);
begin
if Assigned(ComSrm) then
begin
Image1.Picture.Bitmap.LoadFromStream(ComSrm);
ComSrm.Free;
ComSrm := nil;
end;
end;

procedure TForm1.ClientSocket1Connect(...);
begin
FStream := TStream.Create(ComSrm);
end;

procedure TForm1.btn1SocketsClick(...);
begin
ClientSocket1.Active := True;
end;

end.

Algol
16.03.2009, 01:50
Вместо
RuSrm := TStream.Create;
нужно
RuSrm := TMemoryStream.Create;

из хелпа:
TStream is an abstract or, in C++ terminology, pure virtual class. It should not be instantiated; it relies on abstract or pure virtual methods that must be overridden in descendant classes.

Да, и еще, перед вызовом SendStream
нужно поставить текущую позицию потока в ноль:

RuSrm.Seek(0, soFromBeginning);
Socket.SendStream(RuSrm);

Flame of Soul
16.03.2009, 09:48
нужно
RuSrm := TMemoryStream.Create;
Это не так собственно важно, потому что я именно с ним и работала изначально, но все равно спасибо, теперь буду знать, что надо только с ним.
RuSrm.Seek(0, soFromBeginning);
а про установку в ноль , Вы правы она необходима. Что же, приду домой попробую откомпилировать. Спасибо большое, тему пока не закрывайте пожалуйста, на всякий случай.