1. Computing

Acessing Files With Unknown Structure

Direct Access to Files Regardless of Type and Structuring

By

Using Delphi to manage operations on untyped files - direct access to disk files regardless of type and structuring.

Traditional Delphi (Pascal) file input and output (I/O) can handle three classes of Windows files: text (ASCII), typed and untyped. In this article we will see how and when to use Delphi to access files with no known structure - untyped files.

Untyped Files

In Delphi, untyped files are used when we want to impose the least possible structure on a file. We can read information from an untyped file into any data type. Of course, this can lead to some really strange behaviour on the part of our program if we try to read incompatible data type into our variables.
Untyped file, on the other hand, gives you the fastest way to transfer data from a disk to your program, in the traditional Pascal way.

Copy files

The runtime library does not provide any routine(s) for copying a file. Even though we can directly call the Windows API CopyFile function, or use the TFileStream VCL class to copy a file; let's see how to do file copying with standard Pascal I/O function calls.

The following FileCopy procedure reads in a file (FileFrom) and writes it back to a second file (FileTo).

 procedure FileCopy(const FileFrom, FileTo: string) ;
 var
   FromF, ToF: file;
   NumRead, NumWritten: Integer;
   Buffer: array[1..2048] of Byte;
 begin
   AssignFile(FromF, FileFrom) ;
   Reset(FromF, 1) ;
   AssignFile(ToF, FileTo) ;
   Rewrite(ToF, 1) ;
   repeat

    BlockRead(FromF, Buffer, SizeOf(Buffer), NumRead) ;
    BlockWrite(ToF, Buffer, NumRead, NumWritten) ;
   until (NumRead = 0) or (NumWritten <> NumRead) ;
   CloseFile(FromF) ;
   CloseFile(ToF) ;
 end; 

An untyped file is declared with the word file and nothing more (no data type). When using with untyped files, Reset and Rewrite have a second parameter that defines the record size. Since we don't know nothing about the structure of the file we are copying, we choose a record size of 1 byte - the most primitive data structure.

Note 1: Similar approach can be used when you want to copy a file from the Internet to your local computer.

Note 2: By using this raw approach to files, you cam, for example, make sure that a JPEG file is actually a JPEG file (when storing images in a database table). In other words, down on the byte level you can check for a specific file signature.

Read, Write

We always use BlockRead and BlockWrite when working with untyped files. The parameters for both procedures are similar. For example, the BlockRead procedure takes four parameters. The first parameter (FromF) is the name of the file, the second is the name of the data structure, the third is the number of records to read. The fourth parameter is the actual number of records to read.

In the repeat...until loop we first read a block of bytes from our source file using BlockRead then we write this block to our destination file using BlockWrite. After we read our block of bytes our position in the source file is automatically moved to the beginning of the next block of bytes according to the size of our Buffer variable.

Streams

Delphi's runtime library has a better way to do file I/O using streams. File streams are object instances of the VCL TFileStream class used to access the information in disk files. TFileStream has a Handle property that gives you access to the Windows file handle. We'll leave the discussion on Streams for some other occasion.

©2014 About.com. All rights reserved.