将TMemoryStream转换为variant

4
如何将TMemoryStream的内容转换为变体?我使用Delphi 2010。
TMemoryStream存储文件的内容,可以是PDF或JPG(扫描文档)。
文件被保存在MS SQL数据库中。当我进入程序的编辑模式时,我会从数据库中提取该文件的内容到TMemoryStream中。
在编辑文档卡后,我需要将文档返回到数据库。扫描文件也可能发生更改(或替换为其他文件)。为了将记录发送回数据库,我使用一组参数的存储过程——每个字段都有一个参数。我将参数作为变量传递给存储过程。
这就是为什么我需要将TMemoryStream转换为变体的原因。

8
为什么要使用Variant来向数据库传递数据?那不太高效。假设您已经将存储过程包装在自定义函数中,应该为每个参数使用实际的数据类型,或者至少使用array of const,这样可以保留类型信息。对于大型二进制对象字段,您可以使用TStream通过TDataSet.CreateBlobStream()TParam.AsStream进行传输。 - Remy Lebeau
2
你想用什么格式来存储变体中的数据?请记住,变体只是一个容器。 - David Heffernan
Remy,感谢你的两篇文章。我肯定应该将我的变量转换回实际的数据类型。实际上,我现在不记得为什么开始将我的数据视为变量了,所以现在我没有理由不将事情恢复到原来的状态。再次感谢。 - Vasiliy Volkov
2个回答

10

假设你需要 Variant 来保存一个字节数组,你可以使用以下方式:

var
  MS: TMemoryStream;
  V: Variant;
  P: Pointer;
begin
  ...
  V := VarArrayCreate([0, MS.Size-1], varByte);
  if MS.Size > 0 then
  begin
    P := VarArrayLock(V);
    Move(MS.Memory^, P^, MS.Size);
    VarArrayUnlock(V);
  end;
  ...
end;

如果 MS.size = 0 并且您最终将 -1 作为第二个维度传递给 VarArrayCreate,会发生什么? - Mason Wheeler
这不是问题,因为我们可以把 if MS.Size > 0 放在第一位。 - Vasiliy Volkov
3
将高界限设置为-1是有效的,这就是创建空数组的方法。数组中的元素数量计算公式为“高界限 - 低界限 + 1”,因此“-1-0+1”等于“0”。 - Remy Lebeau

4

TMemoryStream没有方便的方法来直接访问内部数据。它提供了一个指针属性,但不提供任何有用的数据类型。然而,如果您使用从TMemoryStream派生的TBytesStream,则可以将流中的数据作为TBytes类型的变量获取。

在此之后,假设您的参数是类型为TParam的标准参数对象,则无需使用变体。您可以这样做:

param.AsBlob := MyTBytesVariable;

或者,甚至比这更简单的方法是直接使用流:
param.AsStream := MyMemoryStream;

(如果你这样做,请确保流的Position先设置为0。)

1
TMemoryStream 没有返回 TBytes 的属性。你可能想要使用从 TMemoryStream 派生的 TBytesStream - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接