Board index » delphi » Indy 10: Last information

Indy 10: Last information


2006-12-07 11:01:56 PM
delphi64
I have 2 little problems with indy components.
1)
If I have the following procedure:
For I := 1 To 10 Do
Begin
TCPClient.IOHandler.WriteLn(Command);
TCPClient.IOHandler.Write(I);
TCPClient.IOHandler.ReadBytes(RI, SizeOf(R));
BytesToRaw(RI, R, SizeOf(R));
Memo1.Lines.Add('Name: '+R.Name);
Memo1.Lines.Add('Info: '+R.Info);
End;
The following records to the number 1 are not correctly read (the value
after the first record is not modified)
But if I create a procedure of external reading to the cycle:
Procedure TForm1.Read( Number : Integer;
Var R : MyRec);
Var
RI : tIdBytes;
Begin
TCPClient.IOHandler.WriteLn(Command);
TCPClient.IOHandler.Write(I);
TCPClient.IOHandler.ReadBytes(RI, SizeOf(R));
BytesToRaw(RI, R, SizeOf(R));
End;
And call it during the cicle:
For I := 1 To 10 Do
Begin
Read(I, R);
Memo1.Lines.Add('Name: '+R.Name);
Memo1.Lines.Add('Info: '+R.Info);
End;
All the records are correctly readed. As it is possible?
2)
If I transfer a file among two computers using a FileStream the speed it
is very very low. How could I increase it?
Thanks,
David
 
 

Re:Indy 10: Last information

"David" <XXXX@XXXXX.COM>writes
Quote
TCPClient.IOHandler.ReadBytes(RI, SizeOf(R));
<snip>
The following records to the number 1 are not correctly read (the value
after the first record is not modified)
You are not clearing the TIdBytes in each iteration of the loop. By
default, ReadBytes() will append the new bytes to the end of the TIdBytes,
preserving the old data. Since you are reading the same number of bytes
each time, I suggest pre-allocating the TIdBytes before entering the loop,
and then set the AAppend parameter of ReadBytes() to False so that the
contents of the TIdBytes are overwritten. For example:
SetLength(RI, SizeOf(R));
For I := 1 To 10 Do
Begin
//...
TCPClient.IOHandler.ReadBytes(RI, SizeOf(R), False);
//...
End;
Quote
But if I create a procedure of external reading to the cycle:
<snip>
All the records are correctly readed.
As it should be, because you are using a fresh TIdBytes buffer each time a
record is retreived.
Quote
If I transfer a file among two computers using a FileStream the speed
it is very very low. How could I increase it?
How exactly are you transferring it? Please show the actual code. Are you
using Write(Stream) and ReadStream()? If not, then why not? IF you are
using then, then there is probably nothing you can do to speed it up. The
speed is dictated by the speed of the hard drive and your available network
bandwidth.
Gambit
 

Re:Indy 10: Last information

Thanks a lot.
As it regards the transfer I use tfilestream to transfer the files and
the procedures are:
Procedure Put_File( IOHandler : TIdIOHandler;
Const FileName : String);
Var
FStream : TFileStream;
Begin
FStream := TFileStream.Create(FileName, fmOpenRead, fmShareDenyWrite);
IOHandler.WriteLn(ExtractFileName(FileName));
IOHandler.LargeStream := True;
IOHandler.Write(FStream, 0, True);
FreeAndNil(FStream);
End;
Function Get_File( IOHandler : TIdIOHandler;
Const Directory : String) : String;
Var
Dir : String;
Dimention : Int64;
FStream : TFileStream;
FileName : String;
Begin
Dir := Directory;
If Copy(Dir, Length(Dir), 1) <>'\' Then Dir := Dir + '\';
FileName := IOHandler.ReadLn;
Dimention := IOHandler.ReadInt64;
FStream := TFileStream.Create(Dir+FileName, fmCreate, fmOpenWrite);
IOHandler.LargeStream := True;
IOHandler.ReadStream(FStream, Dimensione);
FreeAndNil(FStream);
Result := FileName;
End;
Note: If I use Explorer to send a file the speed it is 150 times greater
David
 

Re:Indy 10: Last information

"David" <XXXX@XXXXX.COM>writes
Quote
FStream := TFileStream.Create(FileName, fmOpenRead, fmShareDenyWrite);
IOHandler.WriteLn(ExtractFileName(FileName));
IOHandler.LargeStream := True;
IOHandler.Write(FStream, 0, True);
FreeAndNil(FStream);
You should wrap that in a try..finally or try..except blok so that you free
the stream properly in case the IOHandler throws an exception, ie:
FStream := TFileStream.Create(FileName, fmOpenRead, fmShareDenyWrite);
try
IOHandler.WriteLn(ExtractFileName(FileName));
IOHandler.LargeStream := True;
IOHandler.Write(FStream, 0, True);
finally
FreeAndNil(FStream);
end;
Quote
Dir := Directory;
If Copy(Dir, Length(Dir), 1) <>'\' Then Dir := Dir + '\';
You can use IncludeTrailingBackslash() instead:
Dir := IncludeTrailingBackSlash(Directory);
Quote
FileName := IOHandler.ReadLn;
Make sure to strip off any directory name here as well, in case the other
party tries to send a malicious value that causes you to access sensitive
files:
FileName := ExtractFileName(IOHandler.ReadLn);
Quote
Dimention := IOHandler.ReadInt64;
You don't need that. ReadStream will handle that for you:
FStream := TFileStream.Create(Dir+FileName, fmCreate, fmOpenWrite);
try
IOHandler.LargeStream := True;
IOHandler.ReadStream(FStream, -1, False);
finally
FreeAndNil(FStream);
end;
Gambit
 

Re:Indy 10: Last information

Thanks a lot now all work perfect
David