• Sequential Access Files (Continued)
• Last Lecture Reviewed
• Random Access Files
- Position in a File
- Setting the Position
- Example of seekg() and tellg() Functions
- Example of Data Insertion in the Middle of a File
- Efficient Way of Reading and Writing Files
- Copying a File in Reverse Order
• Sample Program 1
• Sample Program 2
Sequential Access Files (Continued)
In the last lecture, we discussed little bit about Sequential Access Files under
the topic of File Handling. Sequential Access Files are simple character files.
What does the concept of sequential access mean? While working with the
sequential access files, we write in a sequence, not in a random manner. A
similar method is adopted while reading such a file.
In today’s lecture, we will discuss both the topics of File Handling and Random
Before going ahead, it is better to recap of File Handling discussed in the
previous lecture. Let’s refresh the functions or properties of File streams in our
Last Lecture Reviewed
It is so far clear to all of us that we use open () function
to open files. Similarly,
to close a file close () function is used. open ()
has some parameters in its
parenthesis as open (filename, mode) but close ()
brackets remain empty as it
does not have any parameter.
A file can be opened for reading by using the open () function.
It can also be
opened for writing with the help of the same open () function
. But different
argument value will be needed for this purpose. If we are opening for reading
with ifstream (Input File Stream), a simple provision of the
sufficient enough, as the default mode is for reading or input. We can also
provide an additional argument like open ("filename", ios::in).
But this is not
mandatory due to the default behavior of ifstream.
However, for ofstream (Output File Stream), we have several
we open a file for writing, there is default mode available to destroy (delete)
previous contents of the file, therefore, we have to be careful here. On the other
hand, if we don’t want to destroy the contents, we can open the file in append
mode (ios::app). ios:trunc value causes the contents of the
preexisting file by
the same name to be destroyed and the file is truncated to 0 length.
/* Following program writes an integer, a floating-point value, and
a character to a file called ‘test’ */
ofstream out(“test”); //Open in default output mode
if ( !out )
cout << “Cannot open file”;
out << 100 << “ “ << 123.12 << “a”;
If you want to open a file for writing at random positions forward and
backward, the qualifier used is ios:ate. In this case, the
file is at first opened
and positioned at the end. After that, anything written to the file is appended
the end. We will discuss how to move forward or backward for writing in the
file later in this lecture.
/* Following program reads an integer, a float and a character from
the file created by the preceding program. */
ifstream in(“test”); //Open in default output mode
if( !in )
cout << “Cannot open file”;
in >> i;
in >> f;
/* Note that white spaces are being ignored, you can turn
this off using unsetf(ios::skipws) */
in >> ch;
cout << i << “ “ << f << “ “ << ch ;
Besides open() and close () functions,
we have also discussed how to read and
write files. One way was character by character. This means if we read (get)
from a file; one character is read at a time. Similarly, if we write (put), one
character is written to the file. Character can be interpreted as a byte here. On
the other hand, the behavior of stream extraction operator (>>)
insertion operator (<<) is also valid as we just saw in the
above. We will discuss this a little more with few new properties in this lecture.
/* Code snippet to copy the file ‘thisFile’ to the file ‘thatFile’ */
cout << "unable to open ’thisFile’ for input";
ofstream toFile ("thatFile");
if ( !toFile )
cout << "unable to open ’thatFile’ for output";
char c ;
while (toFile && fromFile.get(c))
- Creates an ifstream object called fromFile with a
default mode of ios::in
and connects it to thisFile. It opens thisFile.
- Checks the error state of the new ifstream object
and, if it is in a failed state,
displays the error message on the screen.
- Creates an ofstream object called toFile with a default
mode of ios::out and
connects it to thatFile.
- Checks the error state of toFile as above.
- Creates a char variable to hold the data while it is passed.
- Copies the contents of fromFile to toFile one character at a time.
It is, of course, undesirable to copy a file this way, one character at a time.
This code is provided just as an example of using fstreams.
We have also discussed a function getline (), used to read
(get) one line at a
time. You have to provide how many characters to read and what is the
delimiter. Because this function treats the lines as character strings. If you use
to read 10 characters, it will read 9 characters from the line and add null
character (‘\0’) at the end itself.
You are required to experiment with these functions in order to understand
Random Access Files
Now we will discuss how to access files randomly, forward and backward.
Before moving forward or backward within a file, one important factor is the
current position inside the file. Therefore, we must understand that there is a
concept of file position (or position inside a file) i.e. a pointer into the file.
While reading from and writing into a file, we should be very clear from where
(which location inside the file) our process of reading or writing will start. To
determine this file pointer position inside a file, we have two functions
Position in a File
Let’s say we have opened a file stream myfile for reading (getting),
myfile.tellg () gives us the current get position of the file pointer.
It returns a
whole number of type long, which is the position of the next
character to be
read from that file. Similarly, tellp () function is used to
determine the next
position to write a character while writing into a file. It also returns a
For example, given an fstream object aFile:
Streampos original = aFile.tellp(); //save current position
aFile.seekp(0, ios::end); //reposition to end of file
aFile << x; //write a value to file
aFile.seekp(original); //return to original position
So tellg () and tellp () are the two very
useful functions while reading from or
writing into the files at some certain positions.
Setting the Position
The next thing to learn is how can we position into a file or in other words how
can we move forward and backward within a file. Suppose we want to open a
file and start reading from 100th character. For this, we use seekg ()
() functions. Here seekg () takes us to a certain
position to start reading from
while seekp () leads to a position to write into. These functions
seekg () and
seekp () requires an argument of type long to
let them how many bytes to move
forward or backward. Whether we want to move from the beginning of a file,
current position or the end of the file, this move forward or backward
operation, is always relative to some position.. From the end of the file, we can
only move in the backward direction. By using positive value, we tell these
functions to move in the forward direction .Likewise, we intend to move in the
backward direction by providing a negative number.
aFile. seekg (10L, ios::beg)
We are asking to move 10 bytes forward from the begining of the file.
Similarly, by writing:
aFile. seekg (20L, ios::cur)
We are moving 20 bytes in the forward direction starting from the current
position. Remember, the current position can be obtained using the tellg
aFile. seekg (-10L, ios:cur)
The file pointer will move 10 bytes in the backward direction from the current
position. With seekg (-100L, ios::end), we are moving in the
direction by 100 bytes starting from the end of the file. We can only move in
the forward direction from the beginning of the file and backward from the end
of the file.
You are required to write a program to read from a file, try to move the file
pointer beyond the end of file and before the beginning of the file and observe
the behavior to understand it properly.
seekg() and tellg() Functions
One of the useful things we can do by employing these functions is to determine
the length of the file. Think about it, how can we do it.
In the previous lectures, we have discussed strlen () function
that gives the
number of characters inside a string. This function can also be used to
determine the length of the string placed inside an array. That will give us the
number of characters inside the string instead of the array length. As you
already know that the length of the array can be longer than the length of the
string inside it. For example, if we declare an array of 100 characters but store
"Welcome to VU" string in it, the length of the string is definitely smaller than
the actual size of the array and some of the space of the array is unused.
Similarly in case of files, the space occupied by a file (file size) can be more
than the actual data length of the file itself.
Why the size of the file can be greater than the actual data contained in that
file? The answer is little bit off the topic yet it will be good to discuss.
As you know, the disks are electromagnetic devices. They are very slow as
compared to the controlling electronic devices like Processors and RAM
(Random Access Memory). If we want to perform read or write operations to
the disk in character by character fashion, it will be very wasteful of computer
time. Take another example. Suppose ,we want to write a file, say 53 bytes long
to the disk . After writing it, the next file will start from 54th byte on the disk.
Obviously, this is very wasteful operation of computer time. Moreover, it is
also very complex in terms of handling file storage on the disk.
To overcome this problem, disks are divided into logical blocks (chunks or
clusters) and size of one block is the minimum size to read and write to the
disk. While saving a file of 53 bytes, we can’t allocate exactly 53 bytes but
have to utilize at least one block of disk space. The remaining space of the
block except first 53 bytes, goes waste. Therefore, normally the size of the file
(which is in blocks) is greater than the actual data length of the file. When this
file will be read from the disk, the whole chunk (block) is read instead of the
actual data length.
By using seekg () function, we can know the actual data length
of the file. For
that purpose, we will open the file and go to the end of the file by asking the
seekg () function to move 0 bytes from the end of the file as:
ios::end). Afterwards, (as we are on end of file position), we will call
tellg () to
give the current position in long number. This number is the
actual data bytes
inside the file. We used seekg () and tellg ()
functions combination to
determine the actual data length of a file.
/* This is a sample program to determine the length of a file. The program
accepts the name of the file as a command-line argument. */
main(int argc, char **argv)
cout << "Error opening file in input mode"<< endl;
/* Determine file length opening it for input */
inFile.seekg(0, ios::end); //Go to the end of the file
long inSize = inFile.tellg(); //Get the file pointer position
cout << "The length of the file (inFile) is: " << inSize;
/* Determine file length opening it for output */
cout << "Error opening file in append mode"<< endl;
long outSize = outFile.tellp();
cout << "\nThe length of the file (outFile) is: " << outSize;
Run this program to see its output that shows different results for both input
and output modes. Discuss it on discussion board.
Data Insertion in the Middle of a File
The question arises why to talk about seekg () and
tellg () functions before
proceeding to our original topic of random access to files. This can be wellunderstood
from the following example. Let’s suppose, we have written a file
containing names, addresses and dates of birth of all students of our class.
There is a record of a student, who is from Sukkur. After sometime,
to know that the same student has moved to Rawalpindi. So we
need to update
his record. But that record is lying somewhere in the middle of the file. How
can we update it?
We can search Sukkur using seekg () and
tellg () functions. After finding it,
can we update the word sukkur with the Rawalpindi.
No. It is just due to the
fact that Rawalpindi is longer in length than the word
Sukkur and the
subsequent data of Data of Birth of the student will be overwritten. So the
structure of the file is disturbed and as a result your data file will be corrupted.
This is one of the issues to be taken care of while writing in the middle of a
Let’s think again what is the actual problem. The file is lying on the disk. We
started reading that file and reached somewhere in the middle of the file to
replace data at that position. But the data we are going to replace is shorter in
length as compared to the new one. Consider how is this on the disk. We need
some kind of mechanism to cut the disk, slide it further to make some space to
insert the data into. But this is not practically possible.
In the times of COBOL, the Merge Method was employed to insert data into
the middle of the file. The logic of Merge method is to copy all the data into a
new file starting from beginning of the file to the location where we want to
insert data. So its algorithm is:
- Opened the data file and a new empty file.
- Started reading the data file from beginning of it.
- Kept on copying the read data into the new file until the location we want
insert data into is reached.
- Inserted (appended) new data in the new file.
- Skipped or jumped the data in the data file that is to be overwritten or
- Copied (appended) the remaining part of the file at the end of the new
This is the only way of inserting the data in the middle of a sequential file.
After this process, you may delete the old file and rename the new file with the
same name as that of the old file. This was done in the past . But now
nowadays, it is used some time when the size of the data is not huge. But
obviously, it is very wasteful as it takes lot of time and space in case of largesized
data . The file size can be in hundred of megabytes or even in gigabytes.
Suppose, you have to copy the whole file just to change one word. This is just a
wasteful activity. Therefore, we must have some other mechanism so that we
can randomly read and write data within a file, without causing any disturbance
in the structure of file.
To achieve this objective, we have to have random access file and the structure
of the file should be such that it is not disturbed in case of updations or
insertions in the middle . The language C/C++ does not impose any structure
on the file. The file can be English text or a binary file. Be sure that a language
has nothing to do with it. For a language, a file is nothing but a stream of bytes.
In our previously discussed example of students of a class, it makes lot of sense
that each record of the file (a student record) occupies the same space. If the
record size is different, the updations will have similar problems as discussed
above. So what we need do is to make sure that size of each student data is
identical in the file. And the space we have decided on is large enough such
that, if we wrote Sukkur into it, the spaces were there at
the end of it. If we
want to replace Sukkur with Ralwalpindi
or Mirpur Khas, it can fit into the
same allotted space. It means that the file size remains the same and no
destruction takes place,. So the constant record length is the key element in
resolving that issue of insertion in the middle of the file without disturbing the
structure of the file. Normally, we also keep some key (it is a database
terminology) inside these files. The key is used to locate the record. Consider
the example of students again. Suppose we had written student’s name, say
Jamil Ahmed, city and data of birth, what could we do to locate the
change the student’s information from Sukkur to Rawalpindi.
We could have
written a loop to read the names and to compare it with Jamil Ahmed
the particular record of that student to replace the city to Rawalpindi.
comparison of names is expensive in terms of computation. It could be nicer to
store a serial number with each record of the students. That serial number will
be unique for each student. It can also be roll number or ID number of a
student. So we can say that replace the city of the student with id number
Rawalpindi. So in this case, we will also be doing comparison based
basis of ID numbers of student. Here we have made a comparison again. But is
a number-related comparison, not a string comparison. It will be even easier if
the file is sorted on the basis of student id numbers which have no gaps. If the
data is of 50 students, the first student’s id number is 1 and last one is 50.
Let’s take this example little further. Suppose the record of one student can be
stored in 100 bytes. The student id field that is also contained within these 100
bytes is there in the file to uniquely identify each student’s record.
If we want to read the 23rd student’s record (with id 23) in the file.
One way is
the brute force technique discussed earlier to start a loop from the beginning of
the file to the required student id 23.
We have added following conditions with this file.
- Each student record takes 100 bytes
- The first ten bytes of a record are student id number. Student’s name and
City are 40 characters long respectively and last 10 bytes are for Date of
- The student ids are in order (sorted) and there are no holes in student
let’s say there is 50 students data then the file will start with id 1 student’s
record and end with id 50 student’s record.
After becoming aware of the above-mentioned conditions, can we find a quick
way of finding the 23rd’s student data? The answer is obviously yes
as we know
that one student’s data is taking 100 bytes then 22 student’s data will be 22 *
100 = 2200 bytes. The data for 23rd’s student starts from 2201st
byte and goes
to 2300th byte. We will jump first 2200 bytes of the file using
seekg () function
and there will be no wastage of resources as there are no loops, no if-else
comparisons. After being aware of structure of a student’s record, we can go to
the desired position and perform update operation wherever needed. We can
update the name of the student, change the name of the city and correct the data
of birth etc. So seekg () allows us to jump to any position
in the file.
seekg() is used for input file or for reading from the file while
seekp() is used
for output during the process of writing to the file. Remember, a file opened
with ifstream is used for input and cannot be used for output.
Similarly, a file
opened in output mode using ofstream cannot be used for input
mode. But a
file opened with the help of fstream; can be used for both
purposes i.e. input
and output. The qualifier ios::in || ios::out is passed into
the open () function
while opening the file with fstream for both purposes. Why
are we doing the
OR ‘||’ operation for opening the file in both the modes. You
that when we do OR operation ( if either of the expression is true ), the result
becomes true. The qualifiers ios::in || ios::out are flags
and exist in memory in
the form of 0’s and 1’s. The input flag ios::in has one bit
on (as 1) and output
flag ios::out possesses another bit on. When we perform OR
‘||’ operation to
these two flags, the resultant of this expression contains the bits as on (as 1)
from both of the flags. So this resultant flag bits depict that the file will be
for both input and output . We can use this technique of ORing for other
qualifiers as well. Remember that it is not a case of AND. Although, we want
input and output , yet we have to do OR operation ios::in || ios::out
our desired behavior.
Lets see how can these tricks work
As discussed in the example of data updation within a file, what can happen if
we know the exact things and want to replace a q character
in a sentence? We
should think of the logic first as it has always to be with logic and analysis that
what would be algorithm for a problem. Lets say we wrote a sentence This
an apple in a file and want to change it to This is a sample.
The length of both
the sentences is same.
/* This program firstly writes a string into a file and then replaces
its partially. It demonstrates the use of seekp(), tellp() and write()
int main ()
outfile.open ("test.txt"); // Open the file
outfile.write ("This is an apple",16); // Write the string in the file
pos = outfile.tellp(); // Get the File pointer position
outfile.seekp (pos-7); // Move 7 positions backward
outfile.write (" sam",4); // Write 4 chars in the current position
outfile.close(); // Close the file
Efficient Way of Reading and Writing Files
Let’s consider another example. We know how to read a file character by
character, write into another file or on the screen. If we want to write into a
after reading another file, there are already enough tools to get (read) one
character from a file and put (write) into the other one. We can use
inputFile.getc () to get a character and outputFile.putc
() to write a character
into a file.
As mentioned earlier, there is very inefficient way of doing things . We also
know that for reading and writing to disk, processing in chunks is more
efficient. Can we handle more data than a single byte or a single line? The
answer is yes. We can use read () and write ()
functions for this purpose.
These functions are binary functions and provided as a part of the stream
functions. The term binary means that they read and write in binary mode , not
in characters. We tell a location in memory to read () function
to write the read
data and with the number of bytes to read or write. Usually, read(arrayname,
number of bytes) e.g. read(a, 10).
Now depending on our computer’s memory, we can have a very large data in it.
It may be 64K.
You are required to write two programs:
One program will be used to get to read from a file and put to write into the
other file. Prepare a simple character file using notepad or any other editor of
your choice. Put some data inside and expand the size of the data in the file by
using the copy-paste functions. A program can also be written to make this bigsized
data file. The file size should be more than 40K preferably. Read this file
using getc () and write it another file using putc
(). Try to note down the time
taken by the program. Explore the time () function and find
out how to use it in
your program to note the processing time.
Write another program to do the same operation of copying using read and
write functions. How to do it?
- First declare a character array:
- Call the read function for input file.
- To write this, use the write function for output file.
Here, a loop will be used to process the whole file. We will see that it is much
faster due to being capable of reducing the number of calls to reading and
writing functions. Instead of 10000 getc () calls, we are making
only one read
() function call. The performance is also made in physical reduced disk
(read and write). Important part of the program code is given below:
. . .
. . .
fi.open("inFilename", ios::in); // Open the input file
fo.open("outFilename", ios::out); // Open the output file
fi.seekg(0,ios::end); // Go the end of input file
j = fi.tellg(); // Get the position
fi.seekg(0,ios::beg); // Go to the start of input file
for(i = 0; i < j/10000; i++)
fi.read(str, 10000); // Read 10000 bytes
fo.write(str, 10000); // Wrote 10000 bytes
fi.read(str, j-(i * 10000)); // Read the remaining bytes
fo.write(str, j-(i * 10000)); // Wrote the remaining bytes
fi.close(); // Close the input file
fo.close(); // Close the output file
The fine points in this exercise are left open to discover. Like what happens if
the file length is 25199 bytes. Will our above solution work? Definitely, It will
work but you have to figure out what happened and why does it work. Has the
last read () function call read 10000 bytes? You have to take
care of few things
while doing file handling of character and binary files. Remember that the size
of the physical file on the disk may be quite different from the actual data
length contained in the file.
Copying a File in the Reverse Order
We can also try copying a file in reverse. Suppose, we want to open a text file
and write it in reverse order in a new file after reading. That means the last byte
of the input file will be the first byte of the output file, second last byte of
input file will be the second byte of the output file until the first byte of the
input file becomes the last byte of the output file. How will we do it?
Open the input file. One of the ways of reading the files is to go to its end and
start reading in the reverse direction byte by byte. We have already discussed ,
how to go to the end the file using seekg (0, ios:end). By
now, you will be
aware that while reading, the next byte is read in the forward direction. With
the use of seekg (0, ios:end), we are already at end of the
file. Therefore, if
want to read a byte here it will not work. To read a byte, we should position file
pointer one byte before the byte we are going to read. So we don’t want to go to
the end but one byte before it by using:
aFile.seekg (-1, ios::end);
We also know that whenever we read a byte, the file pointer automatically
moves one byte forward so that it is ready to read the next byte. But in our case,
after positioning, the file pointer 1 byte before the end of file and reading 1
has caused the file pointer to move automatically to the end of file byte and
there is no further data of this file to read. What we need to do now to read the
next byte (second last byte of input file) in reverse order is to move 2 positions
from the end of file:
aFile.seekg (-2, ios::end);
Generically, this can also be said as moving two positions back from the
current position of the file pointer. It will be ready to read the next character.
This is little bit tricky but interesting. So the loop to process the whole file
run in the same fashion that after initially positioning file pointer at second
byte, it will keep on moving two positions back to read the next byte until
beginning of the input file is reached. We need to determine the beginning of
the file to end the process properly. You are required to workout and complete
this exercise, snippet of the program is given below:
while( aFile )
cout << aFile.tellg() << endl;
Remember, generally, if statement is very expensive computation-wise. It takes
several clock cycles. Sequential reading is fairly fast but a little bit tedious.
reach to 100th location, you have to read in sequence one by one.
But if you use
seekg () function to go to 100th location, it is very
fast as compared to the
As discussed, in terms of speed while doing file handling are read ()
() functions. The thing needed to be taken care of while using these
that you should have enough space in memory available. We have discussed
very simple example of read () and write ()
functions earlier . But it is more
complex as you see in your text books. Don’t get confused, you remember we
used array . Array name is a pointer to the beginning of the array. Basically, the
read () requires the starting address in memory where to write the
information and then it requires the number of bytes to read. Generally, we
avoid using magic numbers in our program. Let’s say we want to write an
into a file, the better way is to use the sizeof () function
that can write an
integer itself without specifying number of bytes. So our statement will be like:
aFile.write (&i, sizeof (i));
What benefits one can get out of this approach?. We don’t need to know the
internal representation of a type as same code will be independent of any
particular compiler and portable to other systems with different internal
representations. You are required to write little programs and play with this
function by passing different types of variables to this function to see their
sizes. One can actually know that how many bytes take the char type variable,
int type variable or a double or a float type variable.
You are required to write a program to write integers into a file using the
() function. Open a file and by running a loop from 0 to 99, write integer
counter into the file. After writing it, open the file in notepad. See if you can
find integers inside of it. You will find something totally different. Try to figure
out what has happened. The clue lies in the fact that this was a binary write. It
is more like the internal representation of the integers not what you see on the
screen. You are required to play with it and experiment it by writing programs.
It is mandatory to try out the above example . Also experiment the use of
() function to read the above written file of integers and print out
on the screen. Can you see correct output on the screen? Secondly, change the
loop counter to start from 100 to 199, write it using write ()
function and print
it on the screen after reading it into an integer variable using read
Does that work now? Think about it and discuss it on discussion board.
Sample Program 1
/* This is a sample program to demonstrate the use of open(), close(), seekg(),
get() functions and streams. It expects a file named my-File.txt in the
current directory having some data strings inside it. */
/* Declare the stream objects */
ofstream scrn, prnt;
inFile.open("my-File.txt", ios::in); // Open the file for input
cout << "Error opening file"<< endl;
scrn.open("CON", ios::out); // Attach the console with the output stream
while(inFile.get(inChar)) // Read the whole file one character at a time
scrn << inChar; // Insert read character to the output stream
scrn.close(); // Close the output stream
inFile.seekg(0l, ios::beg); // Go to the beginning of the file
prnt.open("LPT1", ios::out); // Attach the output stream with the LPT1 port
while(inFile.get(inChar)) // Read the whole file one character at a time
prnt << inChar; // Insert read character to the output stream
prnt.close(); // Close the output stream
inFile.close(); // Close the input stream
Sample Program 2
/* This sample code demostrates the use of fstream and seekg() function. It will
file named my-File.txt write alphabets into it, destroys the previous contents */
fstream rFile; // Declare the stream object
/* Opened the file in both input and output modes */
rFile.open("my-File.txt", ios::in || ios::out);
cout << "error opening file"<< endl;
/* Run the loop for whole alphabets */
for ( rChar ='A'; rChar <='Z'; rChar++)
rFile << rChar; // Insert the character in the file
rFile.seekg(8l, ios::beg); // Seek the beginning and move 8 bytes forward
rFile >>rChar; // Take out the character from the file
cout << "the 8th character is " << rChar ;
rFile.seekg(-16l, ios::end); // Seek the end and move 16 positions backword
rFile >>rChar; // Take out the character at the current position
cout << "the 16th character from the end is " << rChar ;
rFile.close(); // Close the file
1. Write a program to concatenate two files. The filenames are provide as
command-line arguments. The argument file on the right (first argument)
will be appended to the file on the left (second argument).
2. Write a program to read from a file, try to move the file pointer beyond the
end of file and before the beginning of the file and observer the behavior.
3. Write a program reverse to copy a file into reverse order.
The program will
accept the arguments like:
reverse org-file.txt rev-file.txt
Use the algorithm already discussed in this lecture.
4. Write a program to write integers into a file using the write ()
Open a file and by running a loop from 0 to 99, write integer counter into
the file. After writing it, open the file in notepad. See if you can find
integers inside it.
• Be careful for file mode before opening and performing any operation on
• The concept of File Pointer is essential in order to move to the desired
• tellg(), seekg(), tellp()
and seekp() functions are used for random movement
(backward and forward) in a file.
• There are some restrictions (conditions) on a file to access it randomly.
structure and record size should be fixed.
• Ability to move backward and forward at random positions has given significance
performance to the applications.
• Binary files (binary data) can not be viewed properly inside a text editor
text editors are character based.