File:
It is a medium to store data in a manner that can be later retrieved and displayed either in part or in whole. FILE itself is structure and using structure pointer for every operation.
Data organization:
Before we discussing about file input/output, let us know how data is organized in the disk. All data stored in binary form in disk varies from one OS to another. But it will not affect C programmer since he is using library functions to deal with a particular OS.
Our program C library function OS Disk
File Operations:
The different file operations are,
- Creation of a new file.
- An opening of a new file.
- Reading from a new file.
- Writing to a file.
- Moving a specific location in a file(seeking).
- Closing file.
Before explaining the above, we need to know some functions usually using in the file operations.
fopen() |
Create a new file or to open an existing file. |
||||||||||
fclose() |
To close a file. |
||||||||||
fgetc() |
Reads a character from the input file referenced by fp. |
||||||||||
fputc() |
Writes the character value of the argument c to the output stream referenced by fp. |
||||||||||
fgets() |
Reads up to n-1 characters from the input stream referenced by fp. |
||||||||||
fputs() |
Writes the string s to the output stream referenced by fp. |
||||||||||
fscanf() |
Read strings from a file, but it stops reading after encountering the first space character. |
||||||||||
fprintf() |
As well to write a string into a file. |
||||||||||
fread() |
For Read in binary mode |
||||||||||
fwrite() |
For Write in binary mode |
||||||||||
getw() |
Reads an integer from a file |
||||||||||
putw() |
Writes a integer to a file |
||||||||||
fseek() |
Set the pointer from record to another |
||||||||||
ftell() |
Gives current position in the file. |
||||||||||
rewind() |
Set the position to the begining point |
||||||||||
fflush() |
To remove or flush any data remaining in the buffer. The argument to fflush() must be buffer which we want to flush. |
||||||||||
SEEK_CUR |
Move the pointer with reference to the current position | ||||||||||
SEEK _SET | Move the pointer with reference to the beginning of the file. | ||||||||||
SEEK_END | Move the pointer from the end of the file | ||||||||||
-recsize | Move the pointer back by recsize bytes from the current position. |
File Opening Modes :
All below listed opening modes are the string. So we should use “ ”.
fp=fopen(“ file1.txt”,” r”);
Mode |
Description |
||||
r |
Opens an existing text file for reading purpose. |
||||
w |
Opens a text file for writing. If it does not exist, then a new file is created. Here your program will start writing content from the BEGINNING (overwritten if the file exists) of the file. |
||||
a |
Opens a text file for writing in appending mode. If it does not exist, then a new file is created. Here your program will start appending content in the existing file content. |
||||
r+ |
Reading, modifying existing contents .writing new contents. |
||||
w+ |
Writing new contents (overwritten), reading them back and modifying existing contents. |
||||
a+ |
Reading existing contents. Appending new contents. Cannot modify existing content. |
||||
rb |
For binary mode reading. |
||||
wb |
For binary mode writing. |
||||
ab |
Opens the binary file for appending. | ||||
rb+ |
|
||||
wb+ |
Opens a binary file in both reading and writing mode |
||||
ab+ |
|
Opening a File:
To open a file we use the function fopen(). The opening can be either in Read mode Write mode.
fopen() performs 3 important tasks.
- Searches the file to be open. (Searching the file also doe by the fopen())
- Loads the file from the disk into a place in memory called buffer.
- Sets up a pointer that points to the first character of the buffer. (fopen returns the address of file and collected in structure pointer.)
Buffer:
Why we are using a buffer? Because it would be more inefficient if we are using the disk for each reading or writing. Each time the speed of the execution becomes low. This is where the buffer comes in. It would be sensible if we are opening one file and read or write to it in the buffer, which is a separate memory location in the disk and would not be affecting the other operations of the disk thereby we can increase the execution efficiency.
Imagine if the buffer may become before we close the file. In such cases, the contents in the buffer will be stored to the disk at the same time when the buffer gets full. All these functions are done by library functions.
Trouble in Opening a File:
There are a lot of reasons for the failure of file opening using fopen().
- The file being opened may not be present on the disk at all
- Disk space may be insufficient to create a new file.
- A disk may be write protected or damaged one.
So it is important to make sure that whether a file has been opened successfully before trying to read or write. if the opening fails because of the any mentioned above,fopen() will returns a value NULL(defined in stdio.h as #define NULL 0).
Reading from a File:
Once the file has open for reading by fopen() using the opening mode “r”, the contents from the file are brought into the buffer and sets a pointer to the first character and reads using either of fgetc(),fgets(),fscanf().
Writing to File:
Once the file has open for reading by fopen()using the opening mode “w”, the contents from the file are brought into the buffer and sets a pointer to the first character and reads using either of fgetc(),fgets(),fscanf().
Closing the File:
When we have finished reading or writing from the file, we have to close using fclose(). Once we close the file, we can not read or write to it. If we are opened the for writing purposes two operations would be performed.
- The characters in the buffer would be written to the file on the disk.
- The buffer would be eliminated from the memory.
We will discuss the above concepts by explaining a program.
In this program, we are coping from one file to another.
/*Program to COPY from ONE FILE TO ANOTHER. */
#include <stdio.h>
#include <stdlib.h>
int main()
{ FILE *fr,*fw; // because of we need of two files, setting two file pointer.
char ch; //Setting 1 character for receiving character from first file and to store.
fr = fopen(“file1.txt”, “r”);
/*File1 opening in ‘r’ mode.Now the pointer ‘fr’ is set to the staring position, by assigning the starting address.*/
if(fr == NULL)
// BY assigning NULL to pointer fr ,we can check whether the file is created or not.//
{
printf(“Error!”);
exit(1);
/*The call to exit() (defined in stdlib.h)terminates the execution of the program. Usually ‘0’ is passed to exi(0) if the termination is normal, otherwise a non zero value.*/
}
else
{
printf(“file1 has opened successfully \n”);
}
fw = fopen(“file2.txt”, “w”);
/*File2 opening in ‘w’ mode. Now the pointer ‘fw’ is set to the staring position, by assigning the starting address.*/
if(fw == NULL)
/* BY assigning NULL to pointer fw ,we can check whether the file is created or not.*/
{
printf(“Error!”);
fclose(fr);
exit(2);
}
else
{
printf(“file2 has opened successfully\n”);
}
while(1)
{
ch=fgetc(fr);
/*Getting the characters one by one from the first file pointer ‘fr’ & storing it to the ‘ch’*/
if(ch==EOF)
/*Checking for the EOF(end of file condition-it is macro defined in stdio.h),if it’s so execution will break.*/
{
break;
}
else
{
fputc(ch,fw);
/* fputc()will transfer the characters from ‘ch’ variable to ‘fw’ pointer of file 2.*/
}
}
printf(“coping from file1 to file2 have done successfully\n”);
fclose(fr);
/* fclose() closing the file means the ‘buffer’ would be eliminated from the memory,after the characters in the buffer written to the file on the disk.*/
fclose(fw);
return 0; /*if the process execution was normal it will return ‘0’, otherwise nonzero*/
}
Text Files and Binary Files:
All the program we wrote ,are in text files. Some of the files would not properly work on binary files. In fact all the ASCII codes of these characters are stored in text files.
EX:file1.txt, file.c ..etc
The binary file is a collection bytes. It can be a C program, music files, video files.
Ex:file1.exe, jpg files, Mp3 files…etc…
There are differences in two main areas of text and binary mode file
- Handling newline.
- Storage of numbers.
Text versus Binary Mode:
- Newlines:
A new line character converted into the carriage return-linefeed combination before being written to the disk. Likewise, the carriage return-linefeed combination on the disk is converted back into a new line when the file is ready by a C program.
However, if a file opened in binary mode, as opposed to text mode, these conversions won’t place.
- Storage of Numbers:
Only fprintf() can do the storing of numbers in the disk file. We should know how numbers are stored in the disk file. It is quite different from memory.
Numbers are stored as strings of characters.
Ex:12345 will occupy 5 bytes in disk using fprintf() rather than memory where it is 4 bytes.
Float 123.45 will occupy 4bytes in memory, but disk file it is 5bytes.
One byte for each character.
So the solution to store numbers in binary mode and use functions fread() and fwrite(). Which stores the numbers in binary format. Here each number would take the same number of bytes.
These functions are mostly used when we need to use structures in the file. The format for both is same.
fread(address of the structure, size of the structure in a byte (by using sizeof () operator), no: structures, file pointer))
Database Management:
There is a provision to Add, Modify, List and Delete records, the operations that are imperative in any database management. Following comments would help you in understanding the program easily.
- Addition of records must always take place at the end of existing records in the file, much in the same way you would add new records in a register manually.
- Listing records means displaying the existing records on the screen. Naturally, records should be listed from the first record to the last record.
- While modifying records, first we must ask the user which record he intends to modify. Instead of asking the record number to be modified, it would be more meaningful to ask for the name of the employee whose record is to be modified. On modifying the record, the existing record gets overwritten by the new record.
- In deleting records, except for the record to be deleted, rest of the records must first be written to a temporary file, then the original file must be deleted, and the temporary file must be renamed back to the original.
- Observe carefully the way the file has been opened, first for reading & writing, and if this fails (the first time you run this program it would certainly fail because that time the file is not existing), for writing and reading. It is imperative that the file should be opened in binary mode.
- Note that the file is being opened only once and closed only once, which is quite logical.
- clrscr( ) function clears the contents of the screen and gotoxy( ) places the cursor at an appropriate position on the screen. The parameters passed to gotoxy( ) are column number followed by row number.
Low-Level File I/O:
In low-level programming is not possible to write data as characters or strings. There is only one-way data can be written or read as a buffer full of bytes.
The programmer must set up the buffer for the data, place appropriate values in it before writing, and take them out after writing. This buffer is very part of the low-level program, which is invisible in the high-level program.
Advantages:
-
Since these functions using the same methods as OS write to the disk, they are more efficient.
-
There are only fewer program lines, so it operates faster.
Declaring the Buffer:
The data read from the file is placed in the buffer. The size of the buffer should be declared by the programmer for the efficient operation. Ex: char buffer [512];
Opening & closing a file:
fopen() – Opening the function.
fclose() – Closing the function
There are some permission arguments they can be any of the following,
S_IWRITE – Writing to the file permitted.
S_IREAD – Reading from the file permitted.
Different opening modes are,
- O_CREAT — Create a file for write, if it does not exist.
- O_RDONLY — Open for reading only.
- O_WRONLY — Open for writing only.
- O_RDWR — Creates a file for both reading and writing
- O_APPEND— Opens a file for appending.
- O_BIARY— Opens a file in binary mode.
- O_TEXT— Opens a file in text mode.
- O_TRUNC — Truncate size to 0.
‘O-flags’ are defined in “fcntl.h”. when o-flags are used together, they are combined by OR operator ( | ).
File Handles:
In high-level programming, we using file pointers to handle the file operation. Here we using ‘file handle’ is a number which is assigned a particular file, which is used as file refer. If fopen() returns -1 ,the file is not opened successfully.
An interaction between file and buffer:
Ex: num=read(inhandle,buffer,512);
read() returns the number of bytes actually read. In our example, we assigning the value to the variable num. Both read and write we have to use in while for coping. The value in num will be equal to the buffer size until the end of the file, when the buffer may only be partially full. The variable num, therefore, is used to tell write(), as to how many bytes to write from the buffer to target file.