如何将 Delphi OleVariant 内容转储到文件中?

Posted

技术标签:

【中文标题】如何将 Delphi OleVariant 内容转储到文件中?【英文标题】:How to dump Delphi OleVariant content to the file? 【发布时间】:2019-11-08 13:14:25 【问题描述】:

我有多层应用程序,它使用 OleVariant 变量通过自定义通信框架跨线路发送和接收数据。通常这个 OleVariant 变量的内容来自 TClientDataSet.Data(当然,它是 OleVariant 类型)。我怀疑通信框架会更改此 OleVariant 变量的内容,因此我想在发送数据之前和接收数据之后转储变量的内容。我使用代码:

TmpOrder: OleVariant;
Tmp: TStringList;

Tmp:=TStringList.Create;
try
  Tmp.LoadFromFile('D:\test.txt');
  Tmp.Add('---');
  Tmp.Add(TmpOrder);
  Tmp.SaveToFile('D:\test.txt');
finally
  Tmp.Free;
end;

但是文件的内容是没有意义的。例如,文件的以下内容可以代表TClientDataSet.Data的内容:

---
??

当然,发生了一些不同的事情。

那么 - 如何捕获 OleVariant 变量的内容。

将 TClientDataSet 保存为 XML 不是我的选择,因为通信使用 OleVariant 而不是 XML。

我正在使用 Unciode Delphi(Delphi 2009 及更高版本)。

【问题讨论】:

这取决于变体对象内部的内容。从这里不能说。 OleVariant 几乎可以保存任何内容,包括对应用程序接口的引用。如果不具体了解该变体中的内容,就不可能知道如何将其保存到文件中(甚至无法确定这是否可能——例如,您无法将 Excel 或 Word 的实例保存到文件中)。跨度> 是什么阻止了您在发送端使用 TCDS 的 SavetoFile(..., dfXML) 然后比较两个 XML 文件? 【参考方案1】:

这里是一些将 TClientDataSet.Data 转换为字符串的代码和一个执行它的测试例程。

function VariantToString(V : OleVariant) : String;
  procedure VariantToStringInner(V : OleVariant; var AString : String);
  var
    IsArray : Boolean;
    DimCount : Integer;
    i : Integer;
  begin
    IsArray := VarIsArray(V);

    if not IsArray then begin
      //  Handle the case where V is not an array
      if (VarIsEmpty(V) or VarIsNull(V)) then begin
        AString := AString + ' ';
        exit;
      end
      else
        AString := AString + VarToStr(V);
    end
    else begin
      //  V is an array, so first we need to know how many dimensions it has
      DimCount := VarArrayDimCount(V);

      //  For TClientDataSet.Data the answer AFAIK should be 1
      //  so we'll process only dimension 1
      Assert(DimCount = 1);

      //  Recurse into this proc so that we handle the cases where V[i] is an array
      //  and where it isn't
      for i := VarArrayLowBound(V, 1) to VarArrayHighBound(V, 1) do begin
        VariantToStringInner(V[i], AString);
      end;
    end;
  end;

begin
  Result := '';
  VariantToStringInner(V, Result);
end;

procedure TForm1.TestVarToStr;
var
  V : OleVariant;
  S : String;
begin
  V := 'hello world';
  S := VariantToString(V) + #13#10;

  V := CDS1.Data;
  S := S + VariantToString(V);
  Memo1.Lines.Text := S;
end;

显然,如果您想将结果保存到文件中,只需调用Memo1.Lines.SaveToFile()

我得到的结果是

你好世界 150252241891000240005020003000202027368401000107838566848980692073080651171161111051109904689711610140600000678117109981011144010000047897109101107300010587736884722020200586971081171011073000105877368847220202002010677265787169957679714013006000100000004000200000004000126585847973786786657685694010300044011000578971091014944002000578971091015026567 P>

同样的CDS数据,保存为XML如下:

<?xml version="1.0" standalone="yes"?>  
<DATAPACKET Version="2.0">
<METADATA>
  <FIELDS>
    <FIELD attrname="ID" fieldtype="i4" SUBTYPE="Autoinc"/><FIELD   attrname="Date" fieldtype="date"/>
    <FIELD attrname="Number" fieldtype="i4"/><FIELD attrname="Name" fieldtype="string" WIDTH="20"/><FIELD attrname="Value" fieldtype="string" WIDTH="20"/>
  </FIELDS>
  <PARAMS CHANGE_LOG="1 0 4 2 0 4" AUTOINCVALUE="3"/>
</METADATA>
<ROWDATA>
  <ROW RowState="4" ID="1" Name="Name1"/><ROW RowState="4" ID="2" Name="Name2" Value="AC"/>
</ROWDATA>
</DATAPACKET>

【讨论】:

如果这没有回答你的问题,请解释原因。 没关系,我使用了 CDS.SaveToFile(...),我减少了工作量,但这确实回答了我的问题。谢谢!

以上是关于如何将 Delphi OleVariant 内容转储到文件中?的主要内容,如果未能解决你的问题,请参考以下文章

delphi olevariant 内存泄露怎么解决

delphi中调用一函数function(Index :OleVariant),其中Index :OleVariant应该填写啥,OleVariant是啥

delphi 导出excel

delphi 导出excel

Delphi Cxgrid怎么有选择的导出到Excel

delphi EmbeddedWB控件的问题!