• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 613
  • Last Modified:

Help with String Sizes Problums.

Hi experts I am designing a liveUpdate program creator. anyway the program is going quite well but am having some problums with string anyway I have a recored like the one below in a unit file

Type
    Header = record
    Version : ShortString;
    ProgName : ShortString;
    UpdateFile : ShortString;
    HomePage : ShortString;
    UpDateUrl : ShortString;
    VerFoundInfo : ShortString;
    VerInfo : ShortString;
    DownloadDoneInfo : ShortString;
End;

Ok the record above as you may already tell  am storeing information about the program's update

My problums is that VerFoundInfo will only allow me to add 255 char some times I may need more than this I have tryed to use WideString but when I try to read the info it does not work. or reports errors is there something I am doing wrong please help PS i am only starting to learn Delphi from moveing from VB so any help whoule be helpfull.

PS the recored aboeve I also write to a file I left the code below incase there may be something wrong there.


procedure WriteUpdate(lzFile : String);
Var
    f : File;
Begin
    AssignFile(F,lzFile);
    reWrite(F,1);
    BlockWrite(F,sUpdate,SizeOf(sUpdate));
    CloseFile(F);
End;

procedure ReadUpdate(lzFile : String);
Var
    f : File;
Begin
    AssignFile(F,lzFile);
    Reset(F,1);
    BlockRead(F,sUpdate,SizeOf(sUpdate));
    CloseFile(F);
End;


Thanks.

Var sUpdate : Header;

0
dreamvb
Asked:
dreamvb
1 Solution
 
shaneholmesCommented:
Type

    THeader = class
    public
     Version : String;
     ProgName : String;
     UpdateFile : String;
     HomePage : String;
     UpDateUrl : String;
     VerInfo : String;
     DownloadDoneInfo : String;
     VerFoundInfo : TStringList;
      constructor Create(AVersion, AProgName, AUpdateFile, AHomePage,
                                  AUpDateUrl, AVerInfo, ADownloadDoneInfo : String;
                                  AVerFoundInfo : TStrings);
      destructor Destroy;
    end;

implementation

    constructor THeader.Create(AVersion, AProgName, AUpdateFile, AHomePage,
                                              AUpDateUrl, AVerInfo, ADownloadDoneInfo : String;
                                              AVerFoundInfo : TStrings);

    begin
     inherited Create;
     VerFoundInfo:= TStringList.Create;
     VerFoundInfo.Assign(AVerFoundInfo);
     Version:= AVersion;
     ProgName:= AProgName;
     UpdateFile:= AUpdateFile;
     HomePage:= AHomePage;
     UpdateUrl:= AUpDateUrl;
     VerInfo:= AVerInfo;
     DownLoadDOneInfo:= ADownloadDoneInfo;
    end;

    destructor THeader.Destroy;
    begin
      VerFoundInfo.Free;
      inherited Destroy;
    end;

var
 MyHeader: THeader;

procedure WriteUpdate(lzFile : String);
Var
    f : File;
Begin
    AssignFile(F,lzFile);
    reWrite(F,1);
    BlockWrite(F,MyHeader,SizeOf(TMyHeader));
    CloseFile(F);
End;

procedure ReadUpdate(lzFile : String);
Var
    f : File;
Begin
    AssignFile(F,lzFile);
    Reset(F,1);
    BlockRead(F,MyHeader,SizeOf(TMyHeader));
    CloseFile(F);
End;



MyHeader:= TMyHeader.Create(All your fields here);


Shane
0
 
shaneholmesCommented:
Oops, it was THeader, not TMyHeader

Shane
0
 
dreamvbAuthor Commented:
Hi, shaneholmes

First of all thanks for getting ack so quick. I tryed your code provied but with no look well the code compiles find but my data is not saved to the file unless I am doing something wrong.

anyway I provied some code as to my problum. below

Type
    Header = record
    SomeInfo : ShortString;
End;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
Var
    TheHead : Header;
    f : File;
begin
    TheHead.SomeInfo := 'This is some data that needs to exceed 255 chars';
    AssignFile(F,'c:\myfile.txt');
    Rewrite(F,1);
    BlockWrite(F,TheHead,SizeOf(TheHead));
    CloseFile(F);
end;

procedure TForm1.Button2Click(Sender: TObject);
Var
    TheHead : Header;
    F : File;
begin
    AssignFile(F,'C:\myFile.txt');
    Reset(F,1);
    BlockRead(F,TheHead,SizeOf(TheHead));
    CloseFile(F);
    Memo1.Text := TheHead.SomeInfo;
end;


Ok the code works fine for string <255 after that it does not work anyway hope you can help


0
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.

 
shaneholmesCommented:
Type

    THeader = class
    public
     SomeInfo : String;
      constructor Create(ASomeInfo: String);
     end;

implementation

    constructor THeader.Create(ASomeInfo);
    begin
     inherited Create;
     SomeInfo:= ASomeInfo;
    end;


var
 MyHeader: THeader;


procedure SaveToFile(FileName: String);
var
 MemStr: TMemoryStream;
 I: Integer;
begin
 MemStr:= TMemoryStream.Create;
 WriteStreamStr(MemStr, MyHeader.SomeInfo);
 MemStr.SaveToFile(FileName);
 MemStr.Free;
end;

procedure LoadFromFile(FileName: String);
var
 MemStr: TMemoryStream;
begin
 MemStr:= TMemoryStream.Create;
 MemStr.LoadFromFile(FileName);
 MyHeader.SomeInfo:= ReadStreamStr(MemStr);
 MemStr.Free;
end;

0
 
DragonSlayerCommented:
instead of shortstring, you can also consider

Type
    Header = record
    Version : ShortString;
    ProgName : ShortString;
    UpdateFile : ShortString;
    HomePage : ShortString;
    UpDateUrl : ShortString;
    VerFoundInfo : ShortString;
    VerInfo : Array [0 .. 1023] of Char; // 1K bytes should be enough? :-)
    DownloadDoneInfo : ShortString;
End;
0
 
dreamvbAuthor Commented:
Hi thanks for the exmple but I still cant get the thing to work. I must be doing something wrong. to be fair I never realy played with classes before and this is my first time.

is there any chnage you can provide a small example for me. I am also getting errors back from the ReadStreamStr also.

I know i am draging this question out like but if you can make a small project that will be very helpfull I have also increase the points agian.

Thanks,

0
 
shaneholmesCommented:
If you gibe me an email address, i will send it to you.


Shane

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Contnrs;

type

 THeader = class
 public
  SomeInfo : String;
  constructor Create(ASomeInfo: String);
 end;

  TForm1 = class(TForm)
    procedure FormActivate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
   function ReadStreamStr(Stream : TStream) : string;
   function ReadStreamInt(Stream : TStream) : integer;
   procedure WriteStreamInt(Stream : TStream; Num : integer);
   procedure WriteStreamStr(Stream : TStream; Str : string);
   procedure SaveToFile(FileName: String);
   procedure LoadFromFile(FileName: String);
  end;

var
 Form1: TForm1;
 Headers: TObjectList;

implementation

{$R *.dfm}

constructor THeader.Create(ASomeInfo: STring);
begin
 inherited Create;
 SomeInfo:= ASomeInfo;
end;

procedure TForm1.SaveToFile(FileName: String);
var
 MemStr: TMemoryStream;
 I: Integer;
begin
 MemStr:= TMemoryStream.Create;
 WriteStreamInt(MemStr, Headers.Count);
 for I:= 0 to Headers.Count-1 do
 begin
  WriteStreamStr(MemStr, THeader(Headers[I]).SomeInfo);
 end;
 MemStr.SaveToFile(FileName);
 MemStr.Free;
end;

procedure TForm1.LoadFromFile(FileName: String);
var
 MemStr: TMemoryStream;
 HCount: Integer;
 Header: THeader;
 I: Integer;
begin
 MemStr:= TMemoryStream.Create;
 MemStr.LoadFromFile(FileName);
 HCount:= ReadStreamInt(MemStr);
 for I:= 0 to HCount - 1 do
 begin
  Header:= THeader.Create(ReadStreamStr(MemStr));
  Headers.Add(Header);
 end;
 MemStr.Free;
end;

procedure TForm1.WriteStreamInt(Stream : TStream; Num : integer);
begin
 Stream.Write(Num, SizeOf(Integer));
end;

procedure TForm1.WriteStreamStr(Stream : TStream; Str : string);
var
 StrLen : integer;
begin
 StrLen := Length(Str);
 WriteStreamInt(Stream, StrLen);
 Stream.Write(Str[1], StrLen);
end;

function TForm1.ReadStreamInt(Stream : TStream) : integer;
begin
 Stream.Read(Result, SizeOf(Integer));
end;


function TForm1.ReadStreamStr(Stream : TStream) : string;
var
 StrLen : integer;
begin
 StrLen := ReadStreamInt(Stream);
 if StrLen > -1 then
 begin
  SetLength(Result, StrLen);
  Stream.Read(Result[1], StrLen);
 end
 else
 Result := '';
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
 if fileExists(ExtractFilePath(Application.exeName) + 'Headers.dat') then
  LoadFromFile(ExtractFilePath(Application.exeName) + 'Headers.dat');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 SaveToFile(ExtractFilePath(Application.exeName) + 'Headers.dat');
end;

initialization
 Headers:= TObjectList.Create;
 Headers.OwnsObjects:= True;
finalization
 Headers.Free;
end.
0
 
Slick812Commented:
hello dreamvb, inorder to get Long Strings in and out of a File, you will need to record the Length of each String, as well as the characters in the string . .  I put all String types in your Record


type
  Header = record
    Version : String;
    ProgName : String;
    UpdateFile : String;
    HomePage : String;
    UpDateUrl : String;
    VerFoundInfo : String;
    VerInfo : String;
    DownloadDoneInfo : String;
    end;


here is the code for two functions to write and read this record to and from a FileStream - -



procedure HeaderToFStream(const aHeader: Header; FileStrm: TFileStream);
var
Len: Integer;
begin
Len := Length(aHeader.Version);
FileStrm.WriteBuffer(Len, SizeOf(Len));
if Len > 0 then
  FileStrm.WriteBuffer(aHeader.Version[1], Len);
Len := Length(aHeader.ProgName);
FileStrm.WriteBuffer(Len, SizeOf(Len));
if Len > 0 then
  FileStrm.WriteBuffer(aHeader.ProgName[1], Len);
Len := Length(aHeader.UpdateFile);
FileStrm.WriteBuffer(Len, SizeOf(Len));
if Len > 0 then
  FileStrm.WriteBuffer(aHeader.UpdateFile[1], Len);
Len := Length(aHeader.HomePage);
FileStrm.WriteBuffer(Len, SizeOf(Len));
if Len > 0 then
  FileStrm.WriteBuffer(aHeader.HomePage[1], Len);
Len := Length(aHeader.UpDateUrl);
FileStrm.WriteBuffer(Len, SizeOf(Len));
if Len > 0 then
  FileStrm.WriteBuffer(aHeader.UpDateUrl[1], Len);
Len := Length(aHeader.VerFoundInfo);
FileStrm.WriteBuffer(Len, SizeOf(Len));
if Len > 0 then
  FileStrm.WriteBuffer(aHeader.VerFoundInfo[1], Len);
Len := Length(aHeader.DownloadDoneInfo);
FileStrm.WriteBuffer(Len, SizeOf(Len));
if Len > 0 then
  FileStrm.WriteBuffer(aHeader.DownloadDoneInfo[1], Len);
end;

procedure HeaderFromFStream(var aHeader: Header; FileStrm: TFileStream);
var
Len: Integer;
begin
FileStrm.ReadBuffer(Len, SizeOf(Len));
SetLength(aHeader.Version, Len);
if Len > 0 then
  FileStrm.ReadBuffer(aHeader.Version[1], Len);
FileStrm.ReadBuffer(Len, SizeOf(Len));
SetLength(aHeader.ProgName, Len);
if Len > 0 then
  FileStrm.ReadBuffer(aHeader.ProgName[1], Len);
FileStrm.ReadBuffer(Len, SizeOf(Len));
SetLength(aHeader.UpdateFile, Len);
if Len > 0 then
  FileStrm.ReadBuffer(aHeader.UpdateFile[1], Len);
FileStrm.ReadBuffer(Len, SizeOf(Len));
SetLength(aHeader.HomePage, Len);
if Len > 0 then
  FileStrm.ReadBuffer(aHeader.HomePage[1], Len);
FileStrm.ReadBuffer(Len, SizeOf(Len));
SetLength(aHeader.UpDateUrl, Len);
if Len > 0 then
  FileStrm.ReadBuffer(aHeader.UpDateUrl[1], Len);
FileStrm.ReadBuffer(Len, SizeOf(Len));
SetLength(aHeader.VerFoundInfo, Len);
if Len > 0 then
  FileStrm.ReadBuffer(aHeader.VerFoundInfo[1], Len);
FileStrm.ReadBuffer(Len, SizeOf(Len));
SetLength(aHeader.DownloadDoneInfo, Len);
if Len > 0 then
  FileStrm.ReadBuffer(aHeader.DownloadDoneInfo[1], Len);
end;


 //- - - - - - - - - -  Here are Two button Clicks to write and read the header var to a file


procedure TForm1.sbut_RecToFileClick(Sender: TObject);
var
Hed1: Header;
FileStream1: TFileStream;
begin
Hed1.Version := '1.1.1.1';
Hed1.ProgName := 'Hed1';
Hed1.UpdateFile := 'C:\update.file';
Hed1.HomePage := 'www.somehomepage.com';
Hed1.UpDateUrl := 'ftp.charge.you.com/update.zip';
Hed1.VerFoundInfo := 'Found it';
Hed1.VerInfo := 'Version 1.2 more or less';
Hed1.DownloadDoneInfo := 'Whatever goes here';

FileStream1 := TFileStream.Create('E:\header.hed',
                 fmCreate or fmOpenWrite or fmShareDenyWrite);
HeaderToFStream(Hed1, FileStream1);
FreeAndNil(FileStream1);
end;



procedure TForm1.sbut_ReadRecFileClick(Sender: TObject);
var
Hed1: Header;
FileStream1: TFileStream;
begin
FileStream1 := TFileStream.Create('E:\header.hed',
                 fmOpenRead or fmShareDenyWrite);
HeaderFromFStream(Hed1, FileStream1);
FreeAndNil(FileStream1);
ShowMessage(Hed1.UpDateUrl);
end;

 - - - - - - - - - - - - -  - - - - - -  --

ask questions if you need more information
0
 
dreamvbAuthor Commented:
shaneholmes

Thanks for the code it is now working.

Thank you agian for your help.

Also thanks to all the rest.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now