【问题标题】:Converting TMemoryStream to variant将 TMemoryStream 转换为变体
【发布时间】:2013-01-16 17:16:58
【问题描述】:

如何将 TMemoryStream 的内容转换为变体?我使用的是 Delphi 2010。

TMemoryStream 存储文件的内容,可以是 PDF 或 JPG(扫描文档)。

文件保存在 MS SQL 库中。 当我在程序中进入编辑模式时,我将该文件的内容从 base 提取到 TMemoryStream 中。

编辑文档卡片后,我需要将文档发布回基地。 扫描的文件也可以更改(或替换为其他文件)。 为了回发记录,我使用了一个带有一堆参数的存储过程——每个字段一个。 我将参数作为变体传递给存储过程。

这就是我需要将 TMemoryStream 转换为变体的原因。

【问题讨论】:

  • 您为什么使用Variant 将数据传递到数据库?那不是很有效。假设您已将存储过程包装在自定义函数中,您应该为每个参数使用实际数据类型,或者至少使用array of const,这样您就可以保留类型信息。对于 blob 字段,您可以使用TStream 通过TDataSet.CreateBlobStream()TParam.AsStream 发布该数据。
  • 您想使用什么格式将其存储在变体中。请记住,变体只是一个容器。
  • 雷米,感谢您的两个帖子。我当然应该将我的变体变回实际的数据类型。实际上,我现在不记得为什么我开始将我的数据视为变体,所以现在我没有理由不让事情恢复原状。再次感谢。

标签: delphi memorystream variant


【解决方案1】:

假设你需要 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 会发生什么?
  • 这不是问题,因为我们可以将if MS.Size > 0 放在首位。
  • 将上限设置为 -1 是有效的。这就是创建空数组的方式。数组中的元素个数计算为highbound - lowbound + 1,因此-1 - 0 + 10
【解决方案2】:

TMemoryStream 没有直接访问内部数据的便捷方式。它提供了一个属性,该属性为您提供了一个指针,但没有任何有用的数据类型。但是,如果使用派生自TMemoryStreamTBytesStream,则可以从流中获取数据作为TBytes 类型的变量。

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

param.AsBlob := MyTBytesVariable;

或者,比这更简单,您可以直接使用流:

param.AsStream := MyMemoryStream;

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

【讨论】:

  • TMemoryStream 没有返回TBytes 的属性。您正在考虑TBytesStream,它源自TMemoryStream
猜你喜欢
  • 2012-05-14
  • 1970-01-01
  • 2023-04-06
  • 2015-12-03
  • 1970-01-01
  • 2018-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多