Chapter 8: Basic File IO


Every programmer must know how to work with files. This chapter shows how to work with text files, files that contain records, and files that have no structure or are treated as if they have no structure. Text files are covered first since they are the most common file type.

Working with Text Files

To gain access to a text file you have to use a Text type variable:

var    myFile: Text;

Before you can start working with a file, you have to assign it to the Text variable using the AssignFile procedure. The AssignFile procedure accepts two parameters: the file variable and the file name.

procedure AssignFile(var F; FileName: string);  AssignFile(myFile, 'c:\data.txt');

After you assign a file name to the file variable, you have to determine what you want to do with the file. You can prepare the file for reading, writing, or appending.

Writing to a Text File

To prepare a file for writing, you have to use the Rewrite procedure, which always creates a new empty file. If a file with the same file name already exists, the Rewrite procedure first deletes the existing file and then replaces it with the new, empty file. The Rewrite procedure then opens the file and sets the file position to the beginning.

When working with text files, you only have to pass the Text variable to the Rewrite procedure:

procedure Rewrite(var F: File [; Recsize: Word ]);  Rewrite(myFile); 

When the file is opened and ready for writing, you can use the standard WriteLn procedure to write text to the text file. When writing to a text file, the first parameter passed to the WriteLn procedure has to be the file variable:

procedure WriteLn([ var F: Text; ] P1 [, P2, ...,Pn ]);  WriteLn(myFile, 'cave canem');

Once you're finished with the file, you should always close it to ensure that the file is properly written to the disk and that any memory used in the process is released. To close the file, use the CloseFile procedure, which accepts only one parameter — the file that needs to be closed:

procedure CloseFile(var F);  CloseFile(myFile);

The entire program for writing a line of text to a text file is shown in Listing 8-1.

Listing 8-1: Writing text to a text file

image from book
program Project1; {$APPTYPE CONSOLE} uses   SysUtils; var   myFile: Text; begin   AssignFile(myFile, 'c:\data.txt');   Rewrite(myFile);   WriteLn(myFile, 'cave canem');   CloseFile(myFile); end.
image from book

Reading from a Text File

To prepare the file for reading, you have to use the Reset procedure. The Reset procedure, like the Rewrite procedure, only accepts the file parameter. The Rewrite procedure can be considered safe in the sense that everything works fine as long as the drive and/or directory specified in the file name exists. Unlike the Rewrite procedure, the Reset procedure will fail if the file assigned to the file variable doesn't exist.

To read data from a text file, you can use the ReadLn procedure. The first parameter is the file variable and the second parameter is a string variable that will temporarily hold the value read from the file. The following example shows how to read values from a text file and display them on the screen.

Listing 8-2: Reading text from a text file

image from book
program Project1; {$APPTYPE CONSOLE} uses   SysUtils; var   myFile: Text;   line: string; begin   AssignFile(myFile, 'c:\data.txt');   Reset(myFile);   ReadLn(myFile, line);   WriteLn(line);   CloseFile(myFile);   ReadLn; end.
image from book

This code will work properly as long as the data.txt file exists. If the data.txt file doesn't exist, the program will crash. To ensure that the application doesn't crash when the file doesn't exist, you have to check whether the Reset procedure successfully opened the file.

I/O Errors

To see if an I/O error occurred, you have to call the IOResult function immediately after a call to an I/O procedure like Rewrite or Reset. The IOResult function returns the result of the last I/O operation. If IOResult returns 0, it means that everything went fine.

To check for I/O errors using the IOResult function, you need to disable the automatic I/O error checking first. I/O error checking is enabled and disabled with the $I compiler directive. Usually, automatic I/O checking is disabled before the call to an I/O procedure and automatically re-enabled immediately after that call:

{$I-} I/O procedure call {$I+}

The following example illustrates how to check for I/O errors and read text from the file only if the file was successfully opened.

Listing 8-3: Checking I/O errors

image from book
program Project1; {$APPTYPE CONSOLE} uses   SysUtils; var   myFile: Text;   line: string;   fileName: string; begin   fileName := 'c:\data.txt';   AssignFile(myFile, fileName);   {$I-}   Reset(myFile);   {$I+}   if IOResult = 0 then   begin     ReadLn(myFile, line);     WriteLn(line);     CloseFile(myFile);   end else     WriteLn('Cannot open file: ', fileName);   ReadLn; end.
image from book

Remember that you can call the IOResult function only once after a call to an I/O procedure. This is because the IOResult function resets the result of the last I/O operation to 0. So, if you call the IOResult function twice, the first IOResult call correctly reports an error, but the following call tells you (incorrectly) that everything is okay.

Working with the Entire File

When you want to read an entire text file, you have to read it sequentially until you reach the end of the file. To see if you have reached the end of the file, use the Eof function. The Eof function accepts a single file parameter and returns a Boolean value that tells you if you've reached the end of the file or not:

function Eof [ (var F: Text) ]: Boolean;

Typically, the best way to read a text file is to use a while loop that continues iterating until the end of file is reached. The following example illustrates how to copy the contents of one text file to another using the while not Eof loop (see Figure 8-1).

image from book
Figure 8-1: Copying a text file

Listing 8-4: Copying a text file

image from book
program Project1; {$APPTYPE CONSOLE} uses   SysUtils; var   srcFile: Text;   destFile: Text;   line: string; begin   { try to open the source file }   AssignFile(srcFile, 'c:\data.txt');   {$I-}   Reset(srcFile);   {$I+}   if IOResult = 0 then   begin     { try to open the destination file }     AssignFile(destFile, 'c:\copy.txt');     {$I-}     Rewrite(destFile);     {$I+}     if IOResult = 0 then     begin       { while loop that copies text from source to dest }       while not Eof(srcFile) do       begin         ReadLn(srcFile, line);         WriteLn(destFile, line);         WriteLn('Copying: ', line);       end;     // while not Eof       CloseFile(destFile);       WriteLn;       WriteLn('File successfully copied.');     end;      // if destFile is OK     CloseFile(srcFile);   end;       // if srcFile is OK   ReadLn; end.
image from book

Loading the Text File into a Dynamic Array

If you need to read the entire text file into memory, the easiest way to do so is to read the file into a dynamic array of strings. To do that, you need to know how many lines of text are in the file. Since there are no functions available to do the job for us, we have to create one. To calculate the number of lines in a text file, use the while not Eof loop to count how many lines are in the file and then call Reset to return the position to the beginning of the file.

The following example uses the while not Eof loop in the GetLineCount function to read the number of lines in the text file. The result is then used in the call to the SetLength function to resize the dynamic array.

Listing 8-5: Loading a text file into a dynamic array

image from book
program Project1; {$APPTYPE CONSOLE} uses   SysUtils; var   myFile: Text;   lines: array of string;   cnt: Integer;   fileName: string; function GetLineCount(var ATextFile: Text): Integer; begin   Result := 0;   while not Eof(ATextFile) do   begin     ReadLn(ATextFile);     Inc(Result);   end;   Reset(ATextFile); { move position to the beginning } end; begin   fileName := 'c:\data.txt';   AssignFile(myFile, fileName);   {$I-}   Reset(myFile);   {$I+}   if IOResult = 0 then   begin     { resize dynamic array and load the lines into the array }     SetLength(lines, GetLineCount(myFile));     for cnt := Low(lines) to High(lines) do       ReadLn(myFile, lines[cnt]);     { close file }     CloseFile(myFile);     { work with strings in memory }     for cnt := Low(lines) to High(lines) do       WriteLn(UpperCase(lines[cnt]));   end else     WriteLn('Cannot open file: ', fileName);   ReadLn; end.
image from book

Once the application loads the entire text file into a dynamic array, you can close the file and work with the strings in memory. You can, of course, do whatever you want with the strings in the array, but this code only converts the strings to uppercase (temporarily) using the UpperCase function and displays them on the screen.



Inside Delphi 2006
Inside Delphi 2006 (Wordware Delphi Developers Library)
ISBN: 1598220039
EAN: 2147483647
Year: 2004
Pages: 212
Authors: Ivan Hladni

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net