Random Access Files in C

(Also called binary files)

Random Access files are different from sequential files in two important ways:

*        You can jump instantly to any structure in the file, which provides random access as in an array.

*        You can change the contents of a structure anywhere in the file at any time.

Once one opens a file one can read, write, or seek any arbitrary structure in the file. C maintains a "file pointer" to enable these functions. When the file is opened, the pointer points to record 0 (the first record in the file). Any read operation reads the currently pointed-to structure and moves the pointer to the next record or structure. A write is done at the currently pointed-to structure and moves the pointer down one structure. Seek moves the pointer to the specified record.

The code below demonstrates random access file techniques.

#include <stdio.h>

struct arec{

int x,y,z;

};

/* writes and then reads 5 records

   from the file "junk". */

int main(void)

{

    int i,j;

    FILE *f;

    struct arec myrec;

    /* create the file of 5 records */

    f=fopen("junk","w");

    if (!f)

        return 1;

    for (i=1;i<=5; i++)

    {

        myrec.x=i;

        fwrite(&r,sizeof(struct arec),1,f);

    }

    fclose(f);

    /* read the 5 records */

    f=fopen("junk","r");

    if (!f)

        return 1;

    for (i=1;i<=5; i++)

    {

        fread(&myrec,sizeof(struct arec),1,f);

        printf("%d\n",.rx);

    }

    fclose(f);

    printf("\n");

    /* use fseek to read the 5 records

       in reverse order */

    f=fopen("junk","r");

    if (!f)

        return 1;

    for (i=4; i>=0; i--)

    {

        fseek(f,sizeof(struct arec)*i,SEEK_SET);

        fread(&myrec,sizeof(struct arec),1,f);

        printf("%d\n",myrec.x);

    }

    fclose(f);

    printf("\n");

 

    /* use fseek to read 3rd record,

       change it, and write it back */

    f=fopen("junk","r+");

    if (!f)

        return 1;

    fseek(f,sizeof(struct arec)*2,SEEK_SET);

    fread(&r,sizeof(struct arec),1,f);

    myrec.x=100;

    fseek(f,sizeof(struct arec)*3,SEEK_SET);

    fwrite(&myrec,sizeof(struct arec),1,f);

    fclose(f);

    printf("\n");

    return 0;

}

There are three new functions in the example code , i.e., fread, fwrite and fseek.

The fread function takes four arguments:

*        A memory address

*        The number of bytes to read per block

*        The number of blocks to read

*        The file variable

So the line fread(&myrec,sizeof(struct arec),1,f); specifies 12 bytes to be read (the size of arec) from the file pointed to by f from the current location of the file pointer. The 12 bytes will be stored at the memory address &myrec. One block of 12 bytes is specified.

The fwrite function works the same way, but moves the block of bytes from memory to the file. The fseek function moves the file pointer to an arbitrary byte in the file. You can use three options when seeking:

*        SEEK_SET - moves the file pointer down from the beginning of the file, i.e. from byte 0.

*        SEEK_CUR - moves the file pointer down from its current position.

*        SEEK_END - moves the file pointer up from the end of file. Note you must use negative offsets.