Title: Copy a FileStream from Server to Client
Question: It could be that you want more control over a Filestream-Copyprocess,
e.g. you want to update from time to time a progressbar or to check blocksize in a LAN or WAN. With the Buffer-Solution you get more flexibility and scalability during a Streamprocess.
Answer:
Suppose you declare a Source- and Destname, with read and writebuffer you can copy source to destination in a manageable way, then you create the destination-filename on the client:
// sSourceFileName:= ReadString(sStartFile); from Registry
// sDestFileName:= sDestPath + ExtractFileName(sSourceFileName);
const cDataSize = 2048;
var Reg: TRegistry; //Source is stored in the Reg
fsSource, fsDestination : TFileStream;
sExecCall : string;
pBuffer: Pointer;
iSize, i: integer;
The mainroutine opens two FileStream-objects and copys with read- and writebuffer a predefined size (2048) from the source to the destination. In the meantime a progressbar is updated until fileSize.
try
fsSource:= TFileStream.Create (sSourceFileName, fmOpenRead);
fsDestination:= TFileStream.Create(sDestFileName, fmCreate);
iSize:= fsSource.Size;
//normal way with CopyFrom!
//fsDestination.CopyFrom (fsSource, fsSource.Size);
ProgressBar1.Max:= fsSource.Size;
GetMem(pBuffer, cDataSize);
i:= 1;
while i * cDataSize fsSource.ReadBuffer (pBuffer^, cDataSize);
fsDestination.WriteBuffer (pBuffer^, cDataSize);
ProgressBar1.Position:= i * cDataSize;
inc(i);
end;
fsSource.ReadBuffer (pBuffer^, iSize- (i-1)* cDataSize);
fsDestination.WriteBuffer (pBuffer^, iSize- (i-1)* cDataSize);
finally
fsSource.Free;
fsDestination.Free;
end;
The unit is available to download an needs further actions:
1. two name-entries in the registry in one key // HKEY_USERS
\.DEFAULT\Software\Prosystem\DynaLoader
name value
myExe: 'path to exe'
destinationPath: 'path to client'
2. create the file "regpath.txt" with the registryPath, for example:
// rem HKEY_USERS RegKey on server, 3.8.01
\.DEFAULT\Software\Prosystem\DynaLoader
3. start the loader from clients (a link-file) with two command-line options:
PROLOADER.EXE servername myExe
In our implementation it's only the link (of the loader) and the file on the client, the loader, the application and registry are on the server.
Update 07.04.02 copy a MemoryStream in a StringStream
-------------------------------------------------------
procedure TMainFrm.TemplateBtnClick(Sender: TObject);
var
M: TMemoryStream;
S: TStringStream;
begin
M := TMemoryStream.Create;
S := TStringStream.Create('');
try
M.LoadFromFile(ExtractFilePath(Application.ExeName)+ '/Test1.txt');
M.Seek(0,0);
// TStream.CopyFrom() method uses WriteBuffer()
and ReadBuffer() template methods
S.CopyFrom(M, M.Size);
S.Seek(0,0);
with Memo.Lines do begin
Clear;
Add(S.ReadString(S.Size));
end;
finally
M.Free;
S.Free;
end;
end;