如何将 Delphi OleVariant 内容转储到文件中?
How to dump Delphi OleVariant content to the file?
我有一个多层应用程序,它使用 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 及更高版本)。
这是一些将 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()
我得到的结果是
hello world
150252241891000240005020003000202027368401000107838566848980692073080651171161111051109904689711610140600000678117109981011144010000047897109101107300010587736884722020200586971081171011073000105877368847220202002010677265787169957679714013006000100000004000200000004000126585847973786786657685694010300044011000578971091014944002000578971091015026567
同样的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>
我有一个多层应用程序,它使用 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 及更高版本)。
这是一些将 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()
我得到的结果是
hello world 150252241891000240005020003000202027368401000107838566848980692073080651171161111051109904689711610140600000678117109981011144010000047897109101107300010587736884722020200586971081171011073000105877368847220202002010677265787169957679714013006000100000004000200000004000126585847973786786657685694010300044011000578971091014944002000578971091015026567
同样的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>