
Lesson 9 - File Handling
| |
This
topic deals on how to:
|
| |
|
Intro |
A file contains data which is saved in the hard disk. You can only view a file from the hard disk by using an operating system. A can contain text data which is used by word processors. Many text files are saved in the hard disk with the extensions: *.txt and *.doc. The file with extension of *.txt, means that it is created by the Microsoft Notepad. Whenever you use the Microsoft Notepad and save a text file, this saved file is created and written on to the hard disk. However, some programs have various formats on how to maintain the text - such as justification, font, font colour. So many files contain more data other than text data! The program itself uses various techniques to create a file in such a way that, when it is being read again it can read (using programming skills, etc..) if it is justified, its font style etc..
The program that is able to read the file of extension *.xxx, is called the viewer of that file!
Before you go on with files, please make sure that you have enough hard disk space for our experiments, since I am going to demonstrate to save a file to the hard disk!! :) Only a few kb, however..

|
Read
from a File (file input) |
Reading
a file in pascal is very easy. Note that there are no reserved words
in Pascal that are used to to read or write to a file. We used the 'usual
words': readln() and writeln(); Here's the technique of how to read
a text file (only):
Program Lesson9_Program1;
Var UserFile : Text;
FileName, TFile : String;
Begin
Writeln('Enter the file name '+
+'(with its full path) of the text file:');
readln(FileName);
{A .txt file will be assigned to a text variable}
Assign(UserFile, FileName + '.txt');
Reset(UserFile); {'Reset(x)' - means open the file x}
Repeat
Readln(UserFile,TFile);
Writeln(TFile);
Until Eof(UserFile);
Close(UserFile);
Readln;
End. |
Program code is updated (13th June 2006)
Details: the Assign()function on line 10 has been changed from Assign(UserFile, FileName, + '.txt') to Assign(UserFile, FileName + '.txt') because the comma ',' after 'Filename' is a syntax error.
Program Errors corrected thanks to James McNamara |
I
think that it is worth to take a look at various important lines of
the program. A new variable of type: 'Text' is new to you, and this
should be used whenever you are going to edit a text file! The variable 'FileName' is required to link to the file indicated
by the user. The 'assign' statement is used to declare 'FileName' +
'.txt' to a text file, so that the file could be opened, using - 'Reset()'.
To read from the first line to the very last line of the file, you should
use the repeat-until loop, ending the loop with : 'Until Eof(textfile);',
which means: 'Until the End Of File [eof]'.

|
Create
and Write to a File (file output) |
The
following program is an example of how to create-and-write or overwrite
a file:
Program Lesson9_Program2;
Var FName, Txt : String[10];
UserFile : Text;
Begin
FName := 'Textfile';
Assign(UserFile,'C:\'+FName+'.txt'); {assign a text file}
Rewrite(UserFile); {open the file 'fname' for writing}
Writeln(UserFile,'PASCAL PROGRAMMING');
Writeln(UserFile,'if you did not understand something,');
Writeln(UserFile,'please send me an email to:');
Writeln(UserFile,'victorsaliba@hotmail.com');
Writeln('Write some text to the file:');
Readln(Txt);
Writeln(UserFile,'');
Writeln(UserFile,'The user entered this text:');
Writeln(UserFile,Txt);
Close(UserFile);
End. |
In
the above program, I am using the 'writeln()' statement so that I write
to the file I have previously assigned to. Note that, since I am using
writeln(), there is no output to the screen, it goes
to the file I initialised.
To
check exactly what has just been written to this file, go to C:\, and
see if there is a file named:
Textfile.txt.
Open it and see what does it contain!! :-). If you had problems, or
if you did not have a way out, then in the start menu go to:
start
-> find -> files or folders => look in drive C: and enter 'textfile.txt'
in the text box; double click on it.

|
| Append
text to an existing File |
Writing
to an existing file, means, open a file and add extra data, but not
overwrite the file. Some beginner programmers do not actually understand
how to, not overwrite a file with data they would like to input. This
is the common problem:
Var UFile : Text;
Begin
Assign(UFile,'C:\ADDTEXT.TXT');
ReWrite(UFile);
Writeln(UFile,'How many sentences, '+
+'are present in this file?');
Close(UFile);
End. |
Copy
the program above in a text file editor and save it in the turbo pascal bin folder as 'example.pas'. Open Turbo Pascal, and
run this program for two times or more. Close Turbo Pascal and find
the file named 'addtext.txt'. Is there more than one sentence?
A
new reserved word which works with files, can complete our problem.
The new reserved word is 'append(f)', where f is a variable of type
text. This can be done by simply change the 'Rewrite(UFile)' to 'append(UFile)',
and the text file is not overwritten, but appended! The above program
changes to the following:
Var UFile : Text;
Begin
Assign(UFile,'C:\ADDTEXT.TXT');
Append(UFile);
Writeln(UFile,'How many sentences, '+
+'are present in this file?');
Close(UFile);
End. |
Run
the program two times or more to see the change...

|
Delete
Files |
In
Pascal, the reserved word used to delete files from the hard this is
the 'Erase(f)' where f is a variable of any data type. This means that
'f' could be both file and text variable type. Note, that the file you
are about to delete is not taken in the recycle bin, but it is directly
kicked off the hard disk!!
Unlike
any other file functions, the erase() function does not open the file
to delete it, so you don't need to apply a 'close(...)' after erase().
Example
Program:
Var UFile : Text; { or it could be of 'file' type}
Begin
Assign(UFile,'C:\ADDTEXT.TXT');
Erase (UFile);
End. |

|
| The
'{$I-},{$I+}' compiler directives |
Compiler directives are used to adjust the compiler settings during the compilation process, so that
programmers can control their program in their preferrable way. Compiler directives are declared using the symbols '{', '$' and '}'. Note that the braces are used for comments, but still, '{$something}' is taken to be a directive. Instead of 'something' the programmer should replace it by a known directive (a letter). Now,
the '{$I}' is used to tell the compiler not to take into consideration
I/O errors including file operations. Say, for example, if a file is trying to be opened,
but it does not exist, the program does not stop from executing and halts with a
runtime error, saying: 'File not found' or whatever boring error! Make sense?
So, if you apply this compiler directive before you open the file, either
for writing or reading, I/O errors will not cause the program to raise a runtime error forced halt.
Now,
I must teach you how to use this compiler directive by letting you know
where to put it and how to cater with the error that might occur. It must be placed where you are going to open or delete
a file. ie.:
{$I-}
action on file...
{$I+} { enable the i/o error check again }
It is important to enable again the i/o error check, after you have
disabled it, so that any unknown future errors would be automatically
encountered. However, if you think that it would be better to disable
i/o error checking for the entire program, you can! Just apply the directive
at the beginning and that's it but it is not recommended since during the runtime of your program you will not be notfied of IO errors that might occur!! After you control a file action, you must check whether an error has occured or not by using the system function 'IOResult', which returns IO error information. This is a typical traditional exception handling. You should test for errors using the statement:
If (IOResult <> 0) then ...
The IOResult function should be explicitly used after an IO error check so that it will automatically clear the error flag of the system otherwise, the IO error cause a 'mutation' to other IO processes resulting into a runtime error. You are not required to grasp each word perfectly from what I said. The most important thing is that you include that statement if the IO directives are to be used and everything would be fine. Now I should show you how to use it by
an example:
Program Lesson9_Program3;
Uses Crt;
Var t : Text;
s : String;
Begin
Assign(t,'C:\ABC.DEF');
{$I-} { disable i/o error checking }
Reset(t);
{$I+} { enable again i/o error checking - important }
If (IOResult <> 0) then
Begin
Writeln('The file required to be opened is not found!');
Readln;
End Else
Begin
readln(t,s);
Writeln('The first line of the file reads: ',s);
Close(t);
End;
End. |
If the required file is found the IOResult returns a 0 value, meaning no errors;
ELSE if not found (IOResult returns a non-0 value) display an error message!
IMPORTANT:
if the file is successfuly found, the file is opened and you should
close it as shown in the program above. However, if it is not found,
the common sense says that it couldn't be opened because it is not found!?!
So, you should not include a 'close(..)' after it is not opened and this is done conditionally as shown in the example. Study
carefully my program and run it several times with good paths and non-good
ones to see well the difference and how does the compiler directive
works!!
Hopefully,
the compiler directive could be applied to different functions, similarly
as in the program above. You can use it with 'rewrite()', 'append()',
'erase()', and also 'FSearch()'. You can try as many programs as you
wish and hopefully practicing the IO directive. I know, that this directive is somewhat complex and hard to be
understood but undoubtedly useful! I am there waiting for your e-mails, if you think that your
program does not work properly when using this directive.

|
| Create
and Remove Sub-Directories |
In
Pascal, there are functions with which you can either create or remove
a directory from the hard disk. To create a directoy, we use the function
'createdir(c)' where 'c' is of type PChar. Ohh, that's
sound kinky... What the heck does PChar means? Hehe, PChar is a pointer
variable which holds the address of a dynamic variable of a specified
type. It is sort of a pointer for characters. Before you create the
directory, however, you have to check if the directory exists, else
a runtime error shows up fiddling in front of your monitor!! :-) The
directory is created as follows:
NewDir := FSearch('C:\Pascal Programming',GetEnv(''));
if NewDir = '' then CreateDir('C:\Pascal Programming');
From
only two lines of code, we have been able to create a dir. But, before
you go experimenting on your own, you should strictly read the following
documented example: (I will explain in detail the 'FSearch()' function)
Program Lesson9_Program4;
Uses WinDos, Dos;
{ note the inclusion of the 'windos.tpu' library }
Var NewDir : PathStr;
{ for searching the dir and create a new one,
if it does not exist }
F : Text;
Begin
{ search for the dir }
NewDir := FSearch('C:\Pascal Programming', GetEnv(''));
{ create a new one, if it does not exist }
if NewDir = '' then CreateDir('C:\Pascal Programming');
Assign(F,'C:\Pascal Programming\pprogramming.txt');
{$I+} ReWrite(F); {$I-} { disable and enable back again
i/o error checking }
{ write to text file }
Writeln(F,'http://pascalprogramming.byethost15.com/');
{$I+} Close(F); {$I-}
End. |
The
variable type, 'PathStr', is new to you, and this is a variable defined
in the 'dos.tpu' library. So, you have to include the 'dos' library
at the beginning of your program. The 'FSearch()' function is implemented
also in the windos library to search in a dir list. So, it was useful
in our program and any other program to search if the dir exists or
not. It's not important to know exactly what does 'GetEnv()' mean,
which is found in the second parameter of FSearch(). The Borland Turbo
Pascal reference says that its function is to return the value of the
specified function. Note that 'FSearch()' is implemented in the 'dos.tpu'
library, while CreateDir()' is implemented in the 'windos.tpu' library.
To
remove a directory, it is quite simple. Just add 'remove()' at the end
of your program! :-) Your operating system will automatically erase the dir if
it exists. It doesn't matter if you 'remove' a dir which does not exist.
Hopefully, no runtime errors, will show up! The 'remove(Pch)' function
is also implemented in the windos library, where 'Pch' is a variable
of type PChar, again.

|
| FileSize()
- Return the value of a file in bytes |
Now,
for the fun stuff!! To return the size of a file, simply declare a variable
of 'longint' type, and assign it to the filesize of the file. A file
variable of type byte, should be assigned to the file which you would
like to return its size, using 'assign()'.
Program Lesson9_Program4;
Var f : file of byte; { file var of type byte }
sz : longint; { var for the size }
Begin
Assign(f,'C:\anyfile.txt');
{$I-} Reset(f); {$I+}
f (IOResult <> 0) then
Begin { file found? }
Writeln('File not found.. exiting');
Readln;
End Else
Begin
{ Return the file size in Kilobytes }
sz := round(FileSize(f)/1024);
Writeln('Size of the file in Kilobytes: ',sz,' Kb');
Readln;
Close(f);
End;
End. |

|
| |
|
| |
User Comments
|
| |
|
[HOME][LESSON INDEX][INVITE A FRIEND][FORUM][ABOUT ME]
modified last: September 2005 (Article Version: 2)
mail to: victorsaliba@hotmail.com
© Victor John Saliba 2006 | Privacy Statement | Disclaimer | Contact Us |
|
| |
|