您已经说过,您将只使用该数据集进行读取(不回写到DBMS),并且您的目标实际上只是解压缩获取到客户端的BLOB流。目前没有办法以某种舒适的方式(某种程度上)拦截BLOB获取
拦截BLOB流存储的最近路径将位于
方法(它是转换获取的数据的理想场所,就在它们存储在FireDAC的内部数据存储中之前)。但这需要修改源代码。
在不修改源代码的情况下,您可以为
AfterGetRecord
例如:
procedure TForm1.FDQuery1AfterGetRecord(DataSet: TFDDataSet);
var
BlobStream: TFDBlobStream;
HelpStream: TMemoryStream;
begin
{ create BLOB stream for reading and writing }
BlobStream := DataSet.CreateBlobStream(DataSet.FieldByName('Data'), bmReadWrite) as TFDBlobStream;
try
{ create intermediate stream }
HelpStream := TMemoryStream.Create;
try
{ decompress BLOB stream into helper one }
ZDecompressStream(BlobStream, HelpStream);
{ and overwrite the original BLOB stream content with uncompressed data; note, that
TFDBlobStream must know about the modification, otherwise it won't store the data
into the storage when this stream is released (LoadFromStream won't work here) }
BlobStream.Clear;
BlobStream.Write(HelpStream.Memory^, HelpStream.Size);
finally
HelpStream.Free;
end;
finally
BlobStream.Free;
end;
end;
或者类似地在较低级别:
procedure TForm1.FDQuery1AfterGetRecord(DataSet: TFDDataSet);
var
DataRow: TFDDatSRow;
DataCol: TFDDatSColumn;
InLength: LongWord;
InBuffer: Pointer;
OutLength: Integer;
OutBuffer: Pointer;
begin
{ get the current row storage object }
DataRow := DataSet.GetRow;
{ for column indexing in following calls find column by name }
DataCol := DataSet.Table.Columns.ColumnByName('Data');
{ try to get pointer to the raw data buffer for the column with given index }
if DataRow.GetData(DataCol.Index, rvDefault, InBuffer, 0, InLength, False) then
begin
{ decompress the data buffer into another allocated by this procedure }
ZDecompress(InBuffer, InLength, OutBuffer, OutLength);
try
{ start editing this storage row }
DataRow.BeginEdit;
try
{ let the storage copy the decompressed data from the buffer }
DataRow.SetData(DataCol.Index, OutBuffer, OutLength);
finally
{ finish this storage row editing without creating new row version, so the engine
won't take the data modification as update }
DataRow.EndEdit(True);
end;
finally
{ and release the buffer allocated by ZLib library function call, input buffer used
here belongs to FireDAC's storage }
FreeMem(OutBuffer);
end;
end;
end;