Solved

Saving,rading a Variant to file.

Posted on 2000-04-13
10
337 Views
Last Modified: 2010-04-04
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
Comment
Question by:flooder
  • 5
  • 3
  • 2
10 Comments
 
LVL 2

Expert Comment

by:kubeerja
ID: 2712457
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
 
LVL 2

Expert Comment

by:kubeerja
ID: 2712548
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
 
LVL 1

Author Comment

by:flooder
ID: 2714900
It is a array of variant that is what makes it tricky.

var
  VarArr: Variant;
begin
VarArr:=VarArrayCreate[0,2],varVariant);
0
 
LVL 1

Author Comment

by:flooder
ID: 2714917
According to the Delphi help you cant use file with variants but I will try it any way.
0
 
LVL 1

Author Comment

by:flooder
ID: 2714920
Edited text of question.
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 10

Expert Comment

by:Lischke
ID: 2716202
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
 
LVL 1

Author Comment

by:flooder
ID: 2750476
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
 
LVL 10

Accepted Solution

by:
Lischke earned 200 total points
ID: 2750543
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
 
LVL 10

Expert Comment

by:Lischke
ID: 2750553
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
 
LVL 1

Author Comment

by:flooder
ID: 2765518
I trie it out.
Thanks
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This video discusses moving either the default database or any database to a new volume.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now