Solved

Header in Untyped Files

Posted on 2001-09-18
7
370 Views
Last Modified: 2010-04-06
Hello,

Does anybody know how you can make a 'header' in untyped files?
It's usual to store information in untyped files of the same type, which is specific beforehand. But is it possible to store other information? (example: a header)

What's the difference between typed and untyped files?
I can't find some information about that in Delphi Help..

Greetings,

Wim
0
Comment
Question by:wimhhf
7 Comments
 
LVL 7

Accepted Solution

by:
Motaz earned 100 total points
ID: 6489696
I copy this from my EBook (Delphi Programming Guide) www.geocities.com/motaz1


Untyped file is a kind of files that can be used with any file to perform common file tasks such coping, encryption, compression, and file transfere. These kind of file operations does not care about file type or data type in the file, so that untyped file is very suitable for such files.

There is no transformation in untyped file, in other meaning when you read a buffer from file, data format in the buffer will be the same format in file.


Untyped file in Object Pascal

Untyped file in Object Pascal declared as file, reading, writing, and other manipulation described below:

---------------------------------------------------------------------------------------------------------------------------------------------------------
Operation                            proc/func
---------------------------------------------------------------------------------------------------------------------------------------------------------
Declaration                           var  F: file;
Assigning                             AssignFile(F);
Opening for reading               Reset(F, RecordSize); or Rewrite(F, RecordSize);
Opening for writing                Rewrite(F, RecordSize) or Reset(F, RecordSize)
                   with FileMode = 2
Opening for read/write           Reset(F, RecordSize) with FileMode = 2
Appending                           FileMode:= 2; Reset(F, RecordSize);
                   Seek(F, FileSize(F));
Reading                               BlockRead(F, Buf, Count, [NumRead]);
Writing                                 BlockWrite(F, Buf, Count, [NumWritten]);
Goto random position            Seek(F, Position); { Position is a number of desired record }
Closing file                           CloseFile(F);
Getting records count            FileSize(F);
Getting current position         FilePos(F);
---------------------------------------------------------------------------------------------------------------------------------------------------------

Untyped files organized as random access files so that you can open it in reading/writing mode and you can goto any record randomly using Seek procedure.

Reset in untyped file opens file for reading, writing, or reading and writing mode according to FileMode variable:

If FileMode = 0  that means read only
If FileMode = 1  that means write only
If FileMode = 2  that means read and write access

Befor openning file with reset make sure that the file is exists.

Rewrite in typed file create a new file and it overwrite the file if it is already exists. When you create file with Rewrite you can read and write from and to file.

Append does not work with typed files, insead you must open file with reset and goto beyond last record such as:

FileMode:= 2;  // Read and write mode
Reset(F, 1);
Seek(F, FileSize(F));

If file size if 5 that means there is 5 records in file from 0 to 4 so that going to record number 5 will ensures writing on an empty record. This works only if file exists but it will rais an exception if file does not exists, so that you must write:

AssignFile(F, FileName);
FileMode:= 2;  // Read and write mode
if FileExists(FileName) then
  Reset(F)
else
  Rewrite(F);  // Create new file
Seek(F, FileSize(F));

You must determine record size when openning untyped file with reset or rewrite such as:

Reset(F, 1);  // Record size = 1 byte
Rewrite(F, SizeOf(Rec)); // Record size = size of Rec variable


Example:

{ Function of file copy }

function FCopy(SourceName, TargetName: string): boolean;
var
  SourceF, TargetF: file;
  Buf: array [0 .. 1023] of byte;
  NumRead: integer;
begin
  Result:= false;
  try
    AssignFile(SourceF, SourceName);
    AssignFile(TargetF, TargetName);
    FileMode:= 0; // Read only for source file
    Reset(SourceF, 1); // Record size = 1 byte
    Rewrite(TargetF, 1); // Create target file (destination)

    (*** Coping ***)
    while not Eof(SourceF) do
    begin
      BlockRead(SourceF, Buf, SizeOf(Buf), NumRead);
      BlockWrite(TargetF, Buf, NumRead);
    end; // while not Eof..
    CloseFile(SourceF);
    CloseFile(TargetF);
    Result:= True;

  except
    on E: EInOutError do
    begin
      MessageDlg(E.Message, mtError, [mbOk], 0);
      exit;
    end; // on E:..
  end; // try
end;


{ Example of using FCopy function }

if FCopy('c:\autoexec.bat', 'c:\autoexec.foo') then
  ShowMessage('1 file copied')
else
  ShowMessage('Error while copy file');

Notes:

- There is no transformation in untyped file, buffer are read from disk to RAM without any modification, moreover you can read more than one record at a time, as the example above you can read up to 1024 record at one time, these two features make untyped file the fastest file type in Object Pascal and make it the best choice of coping, encryption, compression, and similar file manipulation.
 
 
0
 
LVL 7

Expert Comment

by:Motaz
ID: 6489702
and this about typed files:

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

Typed files or data files used to store homogeneous data such as bytes, integers, records, user-defiened types, and other Object Pascal types.

Typed files in Object Pascal

Typed files in Object Pascal declaration depends on record type but the main structure of declaration is:

var
  F: file of <Type>;

Type can be any object Pascal type but not Object such as:

var
  IntF: file of integer;
  CharF: file of char;
  RecF: file of TRec;

The most important procedures and functions used with typed files are below:

---------------------------------------------------------------------------------------------------------------------------------------------------------
Operation                            proc/func
---------------------------------------------------------------------------------------------------------------------------------------------------------
Declaration                           var  F: file of <Type>;
Assigning                             AssignFile(F);
Opening for reading               Reset(F); or Rewrite(F);
Opening for writing                Rewrite(F) or Reset(F) with FileMode = 2
Opening for read/write           Reset(F) with FileMode = 2
Appending                           FileMode:= 2; Reset(F); Seek(F, FileSize(F));
Reading                               Read(F, X); { X is a variable of same file type }
Writing                                 Writ(F, X);
Goto random position            Seek(F, Position); { Position is a number of desired record }
Closing file                           CloseFile(F);
Getting records count            FileSize(F);
Getting current position         FilePos(F);
---------------------------------------------------------------------------------------------------------------------------------------------------------

Typed file is organized as random access file so that you can open it in reading/writing mode and you can goto any record directly using Seek procedure.

Reset in typed file opens file for reading, writing, or reading and writing mode according to FileMode variable:

If FileMode = 0  that means read only
If FileMode = 1  that means write only
If FileMode = 2  that means read and write access

Befor openning file with reset make sure that the file is exists.

Rewrite in typed file create a new file and it overwrite the file if it is already exists. When you create file with Rewrite you can read and write from and to file.

Append does not work with typed files, insead you must open file with reset and goto beyond last record such as:

FileMode:= 2;  // Read and write mode
Reset(F);
Seek(F, FileSize(F));

If file size if 5 that means there is 5 records in file from 0 to 4 so that going to record number 5 will ensures writing on an empty record. This works only if file exists but it will rais an exception if file does not exists, so that you must write:

AssignFile(F, FileName);
FileMode:= 2;  // Read and write mode
if FileExists(FileName) then
  Reset(F)
else
  Rewrite(F);  // Create new file
Seek(F, FileSize(F));





Example:

(*********  Save data  **********)

procedure SaveData;
var
  F: file of integer;
  Data: integer;
begin
  AssignFile(F, 'Test.Dat');
  Rewrite(F);
  Repeat
    Data:= StrToInt(InputBox('Data entry',
      'Enter any numbers, enter 0 to stop data entry', ''));
    Write(F, Data);
  until Data = 0;
  CloseFile(F);

end;

(*********  Read data  **********)

procedure ReadData;
var
  F: file of integer;
  Data: integer;
begin
  AssignFile(F, 'Test.Dat');
  FileMode:= 0;  // Read only
  Reset(F);
  while not Eof(F) do
  begin
    Read(F, Data);
    ShowMessage(IntToStr(Data));
  end; // while
  CloseFile(F);

end;


Notes:

- If you want to open typed file for reading you must set FileMode to  0 because if you do not assign 0 to FileMode the default value of it will be 2 which means read and write access. If you open a read-only file or a file in CD-ROM and you want to read it, openning it with reset means read and write if FileMode = 2 which will generates access denied error and prevent you from reading file.

- Records in typed files have a fixed length, so that it does not require any seperator, example if you write three records in a typed file and record size is 10 bytes, actual file size will be 30.

- You can not  write long string in typed file, instead you have to determine it's size such as:

type
  TLine = String[30];
var
  F: file of TLine;
  Line: TLine;


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

Motaz
0
 
LVL 8

Expert Comment

by:Cesario
ID: 6489721
hi wimhhf;

Your header:

Type
  THeader = Record
     ID      : String[4];
     Version : Word;
     Author  : String[30];
  End;

VAR
  myHeader : tHeader;
  f        : File;
Begin
 // Init. your Header
 AssignFile(f,myHeader );
 Rewrite(f,1);
 BlockWrite ( f,Header,SizeOf(Header));
 // Read other Blocks
 CloseFile(f);
End.


The difference between typed and untyped files:

Typed Files:
  Example :

    TAdr = Record
      Name : String[30];
      Tele : String[30];
    End;

VAR
  F : File OF TADR;
  Rec : TAdr;

To Read an Addres form the File Read ( f, Rec);
To Write an Addres to the file ( f, Rec);

Best Regards

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

 
LVL 2

Expert Comment

by:gikam
ID: 6489847
u can use a typed file and use the first record for the header. This is how I do. I think its the easyest way
0
 

Author Comment

by:wimhhf
ID: 6489881
Thanks for your detailed answer, but I have still a question.

I have 2 records:

TPerson = record
  ID: LongInt;
  Name: string[15];
  Phone: string[10];
end;

TOther = record
  Owner = string[20];
  Date = string[20];
  Count = LongInt;
end;

Is it possible to make a typed file where I store records of TPerson.
But in the beginning of the typed file I put a record of TOther (like a header).

or in a different way:

Is it possible to make a untyped file where I store records of TPerson and other records/integer/strings.
But I don't understand exactly how to read/write the records and the strings like I do in a typed file...

In short: I'd like to store records in a file, but I'd to store also other variables in the same file. I know it is possible, but how to do is a bit fuzzy for me.

Greetings,

Wim
0
 
LVL 7

Expert Comment

by:Motaz
ID: 6490025
You can do this:

var
  Person: arra [1 .. 20] of TPerson;
  Other: TOther;
  F: file;
  i: Integer;
begin
  Assign..
  Rewrite(F, 1);
  // Write other as a header:
  BlockWrite(F, Other, SizeOf(Other));
 
  // Write persons:
  for i:= 1 to 20 do
    BlockWrite(F, Person[i], SizeOf(TPerson));
  CloseFile(F);
end;

to read:

  BlockRead(F, Other, SizeOf(Other), NumRead);
  i:= 0;
  while not eof (F) do
  begin
    Inc(i);
    BlockRead(F, Person[i], SizeOf(TPerson), NumRead);
    // Display the records
  end;
  CloseFile(F);


I hope you mean this

Motaz
0
 

Author Comment

by:wimhhf
ID: 6490555
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

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
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.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

743 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

14 Experts available now in Live!

Get 1:1 Help Now