I would like to concatenate some TStringStreams into one Stream.
I have some blob (varbinary(max)) fields in SQL Server and and I want to create a stream from all the rows then save it to a file.
var
// MSWord: Variant;
i: Int32;
sA: TStringStream;
sP: TStringStream;
s: TStringStream;
// fString: TStrings;
begin
sA := TStringStream.Create;
s := TStringStream.Create;
sP := TStringStream.Create;
try
with DateED do
begin
BlobField.SaveToStream(sA);
sA.SaveToStream(s);
// s.CopyFrom(sA, sA.Size);
// s.LoadFromStream(sA);
s.Position := sA.Size;
end;
with DateED.spED_TemplateParagraf do
begin
First;
while not EOF do
begin
DateED.BlobField.SaveToStream(sP);
sP.SaveToStream(s);
s.Position := sP.Size;
sP.Clear;
Next;
end;
end;
s.SaveToFile('D:\test.doc');
finally
sA.Free;
s.Free;
sP.Free;
end;
For some reason this does not do the trick, anyone can help me with a suggestion? How can I concat my Blob fields?
EDIT :
So after trying David's solution
procedure CopyBlobFieldToStream(ds: TDataSet; field: TBlobField; outputStream: TStream);
var
inputStream: TStream;
begin
inputStream := ds.CreateBlobStream(field, bmRead);
try
outputStream.CopyFrom(inputStream, inputStream.Size);
finally
inputStream.Free;
end;
end;
....
stream := TFileStream.Create(fileName, fmCreate);
try
CopyBlobFieldToStream(ds, field1, stream);
CopyBlobFieldToStream(ds, field2, stream);
finally
stream.Free;
end;
I still can't find all the info from the fields into
var
i: Int32;
stream: TFileStream;
Path1: string;
WordApp: TWordApplication;
begin
Path1 := IncludeTrailingPathDelimiter(GetEnvironmentVariable('TEMP')) +
FormatDateTime('yyyymmddhhnnssz', Now) + '.doc';
WordApp := TWordApplication.Create(nil);
stream := TFileStream.Create(Path1, fmCreate);
try
try
with dm do
begin
DataSet.First;
CopyBlobFieldToStream(dm.DataSet,
dm.DataSetBlobField, stream);
ShowMessage(IntToStr(stream.Size));
DataSet.Next;
CopyBlobFieldToStream(dm.DataSet,
dm.DataSetBlobField, stream);
ShowMessage(IntToStr(stream.Size));
CopyBlobFieldToStream(dm.DataSet2,
dm.DataSet2BlobField, stream);
ShowMessage(IntToStr(stream.Size));
end;
finally
stream.Free;
end;
WordApp.Documents.Open(Path1, EmptyParam, False, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam);
WordApp.Visible := True;
finally
WordApp.Free;
end;
This is the way I call, but in the Word dock I only find the text from the first blob field but indeed the stream size is increasing.
A string stream is the wrong tool for the job. You don't have text, you have binary data. You are simply looking to concatenate two binary BLOBs. Do that with code something along these lines:
procedure ConcatenateBlobField(ds: TDataSet; field1, field2: TBlobField; outputStream: TStream);
var
inputStream: TStream;
begin
inputStream := ds.CreateBlobStream(field1, bmRead);
try
outputStream.CopyFrom(inputStream, inputStream.Size);
finally
inputStream.Free;
end;
inputStream := ds.CreateBlobStream(field2, bmRead);
try
outputStream.CopyFrom(inputStream, inputStream.Size);
finally
inputStream.Free;
end;
end;
In order to save to a file, create a TFileStream
and pass it to the function.
stream := TFileStream.Create(fileName, fmCreate);
try
ConcatenateBlobFields(ds, field1, field2, stream);
finally
stream.Free;
end;
Or perhaps like this:
procedure CopyBlobFieldToStream(ds: TDataSet; field: TBlobField; outputStream: TStream);
var
inputStream: TStream;
begin
inputStream := ds.CreateBlobStream(field, bmRead);
try
outputStream.CopyFrom(inputStream, inputStream.Size);
finally
inputStream.Free;
end;
end;
....
stream := TFileStream.Create(fileName, fmCreate);
try
CopyBlobFieldToStream(ds, field1, stream);
CopyBlobFieldToStream(ds, field2, stream);
finally
stream.Free;
end;