Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 457
  • Last Modified:

Saving,rading a Variant to file.

I need to procedure that can help me to save and read a variant to file. This variant will most of the times be in array format of which the size will greatly vary. I think tfilestream must be used but I have no idea how to use it.
Any help appreciated.
0
flooder
Asked:
flooder
  • 5
  • 3
  • 2
1 Solution
 
kubeerjaCommented:
Can this help you :

procedure VarArraySaveFile(const FileName: string ; varData : Variant);
var
 F: file;
 Size: Integer;
 Data: PChar;
begin
 AssignFile(F, FileName);
 ReWrite(F, 1);
 size:=VarArrayHighBound(varData,1) ;
 try
   Data := VarArrayLock(varData);
   try
     BlockWrite(F, Data^, size+1);
   finally
     VarArrayUnlock(varData);
   end;
 finally
   CloseFile(F);
 end;
end ;


0
 
kubeerjaCommented:
the variant should be an array of type varByte. you can add this to the procedure after begin to test for array

 if not VarIsArray(varData) then
  messagedlg('Wrong Variant format',mtError,[mbOK],0) ;
0
 
flooderAuthor Commented:
It is a array of variant that is what makes it tricky.

var
  VarArr: Variant;
begin
VarArr:=VarArrayCreate[0,2],varVariant);
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
flooderAuthor Commented:
According to the Delphi help you cant use file with variants but I will try it any way.
0
 
flooderAuthor Commented:
Edited text of question.
0
 
LischkeCommented:
Hi flooder,

I have seen your other question about widestring variants and files and from this I assume you are on the right track already. The only way I can imaginge to save a variant to a stream (a file is nothing else than a special stream) is to handle each and every possible case the variant can contain and save the data in the particular format.

Here's a code snippet I use to write variant data to the registry:

function WritePreferenceFor(PrefName: String; Value: Variant): Boolean;

begin
  Result := False;
  if (PrefName <> '') and (Value <> Null) then
  begin
    if RegInterface = nil then ShowError('Use ''UsePreferencesOf'' before actually accessing a preference');
    with RegInterface do
    begin
      case VarType(Value) and varTypeMask of
        varByte,
        varSmallInt,
        varInteger:
          WriteInteger(PrefName,Value);
        varCurrency,
        varDate,
        varSingle,
        varDouble:
          WriteFloat(PrefName,Value);
        varBoolean:
          WriteBool(PrefName,Value);
        varString:
          WriteString(PrefName,Value);
      else
        ShowError('Unable to write value for: ' + PrefName);
      end;
      Result := True;
    end;
  end;
end;


I think you need the same approach for the file. Btw: Do you also need help for general use of a (file) stream?

Ciao, Mike
0
 
flooderAuthor Commented:
Thanks Lischke.
Thats basically what I am doing at the moment I am still strugling with varOleStr I have no idea how to save that out of a varaint and to retrieve it again. The help file says it is:
Reference to a dynamically allocated UNICODE string.

Olestring is used when you assign a picture in a table to a variant
myvariant:=table1['picture;desc'];

This problem should solve my problem because the rest I can save.
0
 
LischkeCommented:
Oh, this is very easy to do.

1) Retrieve the wide string like

var
  S: WideString;

begin
  S := myvariant; // only if it contains an OLE string, of course
  :
end;

2) Write the size of the string into the stream to ease reading it later and

3) Write the string

Together this should look like:

var
  S: WideString;
  Count: Cardinal;

begin
  S := myvariant;
  Count := Length(S);
  Stream.Write(Count, SizeOf(Count));
  Stream.Write(PWideChar(S)^, 2 * Count); // consider it's two bytes per letter
end;

To read it out just do:

var
  S: WideString;
  Count: Cardinal;

begin
  Stream.Read(Count, SizeOf(Count));
  SetLength(S, Count);
  if Count > 0 then
    Stream.Read(S[1], 2 * Count);
end;

Ciao, Mike
0
 
LischkeCommented:
Oops, sorry, I have seen too late that I already gave you the wide string save code in your other question. So the only valuable information is how to get to the actual string from the variant.

Ciao, Mike
0
 
flooderAuthor Commented:
I trie it out.
Thanks
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 5
  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now