Monday, May 12, 2008

File I/O

Disk based I/O

File :

A file is data written to a persistent storage device like the hard disk or floppy drive . Normally data in a computer is stored and retrieved from a temporary storage device which is known as memory [ RAM] If we wish to store this data for future reference then we will have to write this data to a permanent (persistent)storage device like the hard disk .

Some fundamental concepts regarding file I/O :-

1. Role of operating system ( O.S ) in File I/O

You might create a file in C , C++ , VB , Word etc… But underlying any of these applications is the O.S. It is the O.S that manages the hardware . It interfaces between the H/W and the application .Tit is the OS that reads , writes data to files .It manages the file system .This means as a C programmer , one must know the OS rules regarding file naming conventions , directory structures etc.

2.Block r/w and byte r/w

Data moves from memory to CPU and I/O devices. Both CPU and memory are fast , electrical devices and bytes of data move to and fro . But the I/O devices like the hard disk , floppy drive are electro mechanical devices . The disk rotates during read writes. It would be very slow if the r/w are byte by byte. These devices manage r/w block by block .A block is defined by the OS as some n bytes ..It could be 512 , 1024 , 2048 or 4096 Bytes …Bigger the block size faster the r/w. Basic unit of a file r/w is a block. Even if a file size is logically 100 bytes , physically it would be a minimum of 1 block .

3.I/O is Stream oriented :-

A stream is defined as a logical producer (input stream) or consumer (output stream) of bits. A stream could be a file or a device like keyboard , monitor , printer etc.. .This stream based I/O has the advantage of rendering a uniform approach to managing data whether to a file or a device. Devices are also treated as files.

Text Stream and Binary stream :-

Text data manages data in a simple format . This means all data is converted to corresponding ASCII codes (one to one) and written to files . Data may be numeric or non numeric . Even numbers are treated this way .

For e.g. 123 would be stored as 0000 0001 0000 0010 0000 0011

The data 123 would occupy 3 bytes .

All reads produce the data correctly by converting back ascii to characters. Numeric data is not distinguished from character type of data. This type of r/w are found in text editors like notepad, Dos Edit .

Binary data : Data is converted into specific binary formats based on some algorithms .

For e.g

Suppose we have an integral data quantity = 123 . Asuming that an int is allocated 2 bytes , this data would be stored in 16 bits as (64+32+16+8+2+1) 0000 0000 0111 1011

r/w converts data appropriately. Numeric data is distinguished from character/string type of data .Floats are managed differently from integral data .This type of r/w are found in data base management softwares.

End of file marker EOF :-

Text files carry an End of file marker (EOF -1 , ascii 26 ] while binary files do not have any such marker . The binary mode files keep track of the end of the file by the number of characters in the directory entry of the file .

Handling Of Newline Character

Text files convert newlines(‘\n’) into a combination of ‘\n’ + ‘\r’ (line feed + carriage return) . Likewise every carriage return – line feed combination is converted into a newline character when a file is read from the disk. No such conversions take place in a binary mode file.

Storage Of Numbers

When a text file is stored to a disk the numbers present in the file are also stored as characters . Therefore they occupy one byte per character. Eg the number 1234 would not occupy 2 bytes as an integer would but it occupies 4 bytes . Thus larger numbers will occupy larger space on disk which is undesirable. However in binary mode numbers are stored in binary format . Hence they will occupy the same space on disk as they will in memory.

FILE pointer FILE *fp

You need a FILE pointer * for a file for all read write operations.

A FILE pointer is a special kind of a pointer to a structure that associates a file with some handler .

Once we have established this handler , we use this in coding and not the file name.

The link between the program and the operating system is a structure called FILE which has been

declared in the header file stdio.h .

always include stdio.h file in disk level input/output programs

When a request is made to the operating system to open

a file what we get back is a pointer to the structure FILE.

FILE fp ; /* fp is a pointer variable which contains the address of the structure FILE */

--

The FILE structure contains the following information :-

· File being used

· Its current size

· Its location in memory

· It contains a character pointer which points to the character that will be read.

Predefined stream pointers :-

C defines 5 predefined FILE pointers

  • stdin a pointer to an input stream (keyboard)
  • stdout a pointer to an output stream(monitor)
  • stderr a pointer to the std error device(monitor)
  • stdprn printer
  • stdaux auxillary port

Opening a file with function fopen( ):-

A call to the function fopen( ) returns a FILE * . Before we can read information from a file or write to a file on a disk we must open it. Opening a file establishes a link between the program and the operating system.

Declaration :

FILE * fopen(const char *filename , const char *fileopenmode );

File Opening Modes

A file can be opened in various modes depending upon our need .

If we need only to read a file it can be opened in the read mode or if we have to write information to a file it can be opened in the write mode and so on.

The different modes available for opening a file are:-

File Operation Text file Binary File

Read (input) “r” or “rt” “rb”

Write(output) “w” or “wt” “wb”

Append(output) “a” or “at” “ab”

Read , write , modify “r+” or “rt+” “rb+”

Write and read

Create the file , then read “w+” or “wt+” “wb+”

Append and read “a+” or “at+” “ab+”

Note :

· Write(output) mode creates file . IF the file already exists, a call to fopen( ) destroys the file

· Append mode adds to the end of an existing file. If file does not exist then the file is created. If it exists then the file is not recreated

· A file opened in binary mode should be manipulated in binary mode only

· Text mode is the default mode . So “r” and “rt” are one and the same

Opening a file :-

FILE *fp ;

fp = fopen(“Filename” , “w”);

Trouble in opening a file

· It is possible that when a request is made for opening a file the request may not be granted for various reasons as follows :

· Wrong path / drive was specified

· OS conventions for filename were violated

· Attempting to open a non existent file for reading

· Hardware problem like lack of disk space

At such times fopen() returns a value NULL (defined in stdio.h as #define NULL 0).So each time a file is to be opened a check is to be made .Did we succeed in opening the file ?

#include

main( )

{

FILE *fp ;

fp = fopen(“Test.c”, “r”);

/*

Test.c is the name of the file to be opened in read mode

check whether file has been opened properly

*/

if ( fp == NULL)

{

printf(“ Unable to open file”);

exit(1);

}

}

Reading / Writing To a File

Several file related functions are available .

fputc( ) write one character to a file

Declaration :- int fputc(int ch , FILE *fp ) :

fputc(ch , fp); /* ch is written to file */

fgetc( ) picks up and returns one character from the file

Declaration :

int fgetc(FILE *fp) ;

ch = fgetc(fp);

fgets( ) picks up a string of n characters from a file and places it in the buffer pointed to by s

Declaration:

char *fgets(char *s, int n, FILE *stream) :

fputs( ) writes a string from the buffer pointed to by s to file

Declaration:

int fputs(const char *s, FILE *stream);

feof( ) Macro that tests if end-of-file has been reached on a stream.

Declaration:

int feof(FILE *stream);

returns 0 if end of file reached , else –1

Handling of binary stream as records :

In a binary file I/O , specific number of bytes of binary data is written to a file .This is called as a record. A record could be a structure type of variable. A record is a collection of related data .This is the human perception.For e.g we may have a product record holding product code , name , rate , qty .We may have a student record holding roll number , name , data of birth and so on.

Read / writes in a binary file :

Functions fread( ) , fwrite( ) are used

fread ( ) : Reads a binary stream into a buffer

Declaration:

size_t fread(void *ptr, size_t size, size_t n, FILE *stream);

Copies size bytes into a buffer pointed to by ptr , n times

fwrite( ) : Writes a binary stream from a buffer to a file

Declaration:

size_t fwrite(void *ptr, size_t size, size_t n, FILE *stream);

Copies size bytes , n times from the buffer pointed to by ptr ,to a file associated with the file handler stream

Record by record navigation :-

The C program distinguishes between one record and another by the size of each record .There is no inter record separator

Random Data access :

The function fseek( ) positions the file pointer in a specific position .

Declaration:

int fseek(FILE *stream, long offset, int whence);

offset : Number of bytes as long

The third argument can be specified as a macro :

SEEK_SET 0 Seeks from beginning of file

SEEK_CUR 1 Seeks from current position

SEEK_END 2 Seeks from end of file

Returns 0 if successful else non zero

Finding out file size and number of records :-

The function ftell( ) returns the byte position of the current file pointer position .When the file pointer is at the end of the file then ftell returns the file size in bytes

Declaration:

long ftell(FILE *stream);

Number of records = filesize / size of each record

Program1 : Create a text file and display its contents

#include

main( )

{

FILE *fp ;

char ch ;

clrscr( ) ;

fp = fopen(“Test.c”, “w+”);

if ( fp == NULL)

{

printf(“Unable to open file “);

exit(1);

}

printf(“Type text Press ^z to save file :- \n”);

while((ch = getchar() ) != EOF )

{

fputc(ch , fp);

}

printf(“\n1 File Saved”);

printf(“\nReading file : TEXT.C \n\n”);

rewind(fp); /* go to the beginning of the file */

while( !feof(fp) )

{

ch = fgetc(fp);

putchar(ch);

}

fclose(fp);

getch();

}

Closing a File :-

A call to the function fclose() flushes all the contents of the buffer to the disk before closing the program .fclose() also disassociates the file pointer and the external name that was established by fopen( ) freeing the file pointer for another file.

Program 2:

/* program to copy the contents of one file to another file */

#include

main()

{

FILE *fs , *ft ;

char ch ;

fs = fopen(“file1” ,”r” );

ft = fopen(“file2” , “w”);

if ( (fs == NULL) || (ft == NULL) )

{

printf(“Unable to open file”);

exit(1);

}

while(! feof(fs) )

{

ch = fgetc(fs);

fputc(ch , fp);

}

fcloseall( ) ;

getch();

}

Program 3 :-

#include

#include

main()

{

FILE *fp ;

char str[80] ;

fp = fopen(“file1” , “w+”);

if ( fp == NULL)

{

printf(“File Creation Error”);

exit( 1 ) ;

}

printf(“\n Enter some lines of text \nPress enter key on a blank line to save \n\n”);

while(1)

{

gets(str);

if(strlen(str) == 0 )

break ;

fputs(str , fp );

fputs(“\n”);

}

printf(“1 File Saved\n”);

rewind(fp);

printf(“\nDisplaying contents of file : FILE1 \n\n”);

while( !feof(fp) )

{

fgets(str , 79 , fp );

puts(str);

}

fclose ( fp ) ;

getch();

}

Formatted I/O fscanf( ) , fprintf( )

For reading and writing of characters, strings ,integers and floats we make use of two functions fscanf() and fprintf() respectively .

Program:

/* program to illustrate the use of fprintf() and fscanf() for writing to and reading from a file */

#include

main()

{

FILE *fp , *ft ;

char name[50] , ans = ‘y’ ;

int marks ;

fp = fopen(“student.dbf” , “w”);

if ( fp == NULL )

{

printf(“\n Unable to open file”);

exit( 1 );

}

while(ans == ‘y’ || ans == ‘Y’ )

{

printf(“\n Enter the name and marks of a student :- “);

scanf(“%s %d”, name , &marks);

fprintf ( fp , “%s%d“ , name , marks);

printf (“\n1 Record Created”);

printf(“\nOne more record ? “);

fflush(stdin);

ans = getchar( );

}

fclose( fp ); //data has been written into file and closed.

ft = fopen(“student.dbf”, ”r”) ;

if ( ft == NULL)

{

printf(“\n Unable to open file”);

exit ( 2 ) ;

}

/* Reading the contents of the file till end of file is encountered and printing it on screen */

while ( !feof ( ft ) )

{

if ( fscanf ( ft , “%s %d” , name , &marks) != EOF )

{

printf(“\n %s %d “ , name , marks);

}

}

fclose ( ft ) ;

getch ( ) ;

}

Reading and Writing To A Binary File Using Structures

#include

#include

struct student

{

char name[10] , address[20] ;

int rollno , std ;

} ;

struct student s ;

main()

{

FILE *fp;

int i , recsize ;

char ans = ‘y’ ;

recsize = sizeof (s) ;

clrscr();

fp = fopen(“Student.dat” , “wb+”) ;

/* file is opened in the binary mode for writing */

if ( fp == NULL)

{

printf(“File creation error”);

exit( 1 ) ;

}

while( ans == ‘y’ || ans == ‘Y’)

{

printf(“\n Enter the name , address , rollno and std :- “);

scanf(“%s%s%d%d” , s.name , s.address , &s.rollno , &s.std ) ;

fwrite(&s , recsize , 1 , fp);

printf(“\n Do you want to enter another record (y/n) ? ”);

fflush(stdin);

ans = getchar( ) ;

}

fseek(fp , 0L , SEEK_SET ) ;

/* Position the file pointer to the beginning of file */

printf(“%10s%10s%10s%10s\n\n” , “Name” , “Address” , “Roll No” , “Std” ) ;

while( !feof(fp) )

{

if ( fread(&s , recsize , 1 , fp) == 1)

{

printf(“%10s%20s%10d%10d” , e.name , e.address , e.rollno , e.std);

}

}

fclose(fp);

getch();

}

No comments: