连接 TStringStream

Concatenate TStringStream

我想将一些 TStringStreams 连接成一个 Stream。

我在 SQL 服务器中有一些 blob (varbinary(max)) 字段,我想从所有行创建一个流,然后将其保存到一个文件中。

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;

出于某种原因,这并不能解决问题,有人可以帮我提个建议吗?如何连接我的 Blob 字段?

编辑 :

所以在尝试了 David 的解决方案之后

   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;

我仍然无法从字段中找到所有信息

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;

这是我调用的方式,但在 Word 停靠栏中我只找到第一个 blob 字段中的文本,但流大小确实在增加。

字符串流不是这项工作的错误工具。你没有文本,你有二进制数据。您只是想连接两个二进制 BLOB。使用以下几行代码来做到这一点:

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;

为了保存到文件,创建一个 TFileStream 并将其传递给函数。

stream := TFileStream.Create(fileName, fmCreate);
try
  ConcatenateBlobFields(ds, field1, field2, stream);
finally
  stream.Free;
end;

或者像这样:

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;