Monday, 4 April 2011

Core Java: Thread Forking

IMPLEMENTING RUNNABLE INTERFACE:

To implement Runnable, we must only implement the method called run( ), which is declared as follows:
public void run( )
Inside this method we have to code that constitute the new thread. It is the entry point for another, concurrent thread of execution within our program. This thread will end when run( ) returns. After declaring a class that implements Runnable interface, we should initiate the object of type Thread using one of its several constructors like:
Thread(Runnable threadOb, String threadName)
In this constructor, threadOb is an instance of a class that implements the Runnable interface. This defines where execution of the thread will begin. The name of the new thread is specified by threadName. After the new thread is created, we have to start the thread using start( ) method of Thread class, as it will not start automatically.

For example the following example illustrate the point:

class NewThread implements Runnable
{
Thread t;
NewThread()
{
t=new Thread(this, "MyThread");
System.out.println(t);
t.start();
}
public void run()
{
// Do sht...
System.out.println(" Exiting from the child thread");
}
}

EXTENDING THREAD CLASS:

The second way to create a thread is to create a new class that extends Thread, and then to create an instance of that class. The extending class must override the run( ) method. Here is the same program as above, rewritten to extend Thread:

class NewThread extends Thread
{
NewThread()
{
super("MyThread");
System.out.println(t);
start();
}
public void run()
{
// Do sht...
System.out.println(" Exiting from child thread");
}
}

N.B. if we are not overriding any of Thread’s other methods, it is probably the best approach simply to implement Runnable interface. Moreover that if the class has already been extended from another class then we have to implement Runnable interface.

Core Java: Thread Inplementation

Java’s multithreading system is built upon the Thread class, its methods, and its companion interface, Runnable. Thread encapsulates a thread of execution. We can not directly refer to the ethereal (n. heavenly) state of a running thread, we should deal with it through its proxy, the thread instance that produced it. To create a new thread our program will either extend Thread or implement the Runnable interface.
To start the execution of a thread, we should call the start( ) method for the Thread object. The code that executes in a new thread is always a method called run( ), which is declared like:public void run( ) . Threads other than the main thread in a program always start in the run( ) method for the object that represents the thread. But here is a problem; we are unable to call run method to start a thread, we should call the start( ) method for the object representing the thread and that causes the run( ) method to be called. When we want to stop the execution of a thread that is running, we should call the stop( ) (now depricated) method for the Thread object. This is because, the threads are always run and managed by operating system and a new thread can only be created and started by the operating system. If we were to call run( ) method ourselves, it would simply operate like any other method, running in the same thread as the program that calls it. When we call the start( ) method for a thread object, we are calling a native code method that causes the operating system to initiate another thread from which the run( ) method for the thread object executes. Hence we should start our thread by calling the start( ) method.

Core Java: Exceptions in Java Thread

When the main thread in a single-threaded application throws an uncaught exception, you are likely to notice because the stack trace is printed on the console (and because the program stops).
By invoking stat() method another thread is started, but the run() method is not really the "main" method of the new thread. The run() method is executed inside a context that allows the virtual machine to handle runtime exceptions thrown from the run() method.
All uncaught exceptions are handled by code outside of the run() method before the thread terminates. The default exception handler is a Java method; it can be overridden. This means that it is possible for a program to write a new default exception handler.
The default exception handler is the uncaughtException() method of the ThreadGroup class. It is called only when an exception is thrown from the run() method. The default implementation of the uncaughtException() method is to print out the stack trace of the Throwable object thrown by the run() method (if it is not an object of ThreadDeath class).


Moreover that the basic Thread Exception classes are:

  1. java.lang.IllegalThreadStateException (unchecked exception class): Thrown to indicate that a thread is not in an appropriate state for the requested operation.
  2. java.lang.ThreadDeath (unchecked exception class): It is a sub-class Error (in general programmer should not try to handle them). An instance of ThreadDeath is thrown in the victim thread when the stop method with zero arguments in class Thread is called. An application should catch instances of this class only if it must clean up after being terminated asynchronously. If ThreadDeath is caught by a method, it is important that it be rethrown so that the thread actually dies.
  3. java.lang.InterruptedException (checked exception class): Thrown when a thread is waiting, sleeping, or otherwise paused for a long time and another thread interrupts it using the interrupt method in class Thread.

Friday, 1 April 2011

J2ee: Introduction to JSP tags

The basic JSP component is the JSP tags. I (JBS) will provide you the general overview about the same. Here is a listing of the tags used in Java Server Pages:
  1. Declaration tag
  2. Expression tag
  3. Directive tag
  4. Scriptlet tag
  5. Action tag

Declaration tag:
Declaration tag is used to define functions, methods and variables that will be used in Java Server Pages.
Notation of the Declaration tag is given below:

"<%! ... %>"

General syntax of Declaration Tag:

<%!
// Variables or methods declaration
// This section will be launched at the traslated servlet class directly
Java statement 1;
Java statement 2;
...;
Java statement n;
%>

REMEMBER: Every Java statement will be terminated with (;)

For example:

<%!
private int n = 0 ;
public int meth( int sth)
{
//Java Statements ;
}
%>


Expression tag:
Expression tag is used to display output of any data on the generated page. The data placed in Expression tag prints on the output stream and automatically converts data into string. The Expression tag can contain any Java expression used for printing output equivalent to out.println().Thus, an expression tag contains a scripting language expression which is evaluated, automatically converts data to a String and the outputs are displayed.
Notation of Expression tag is given below:

<%= ... %>

General syntax of Expression Tag:

<%=
// This section will bw launched within the out.print() method, within _jspservice() method, within the translated servlet class
//Java Expression to be printed out
%>


For example:

<%=new java.util.Date() %>


Directive tag:
Directives are JSP elements that provide global information about an entire JSP page. An example would be a directive that indicated the language to be used in compiling a JSP page. The syntax of a directive is as follows:

<%@ directive {attribute="value"} %>

This states that, for this page directive, assign these values for these attributes. A directive can contain n number of optional attribute/value pairs. The following line of code would indicate that the JSP language to use would be Java:

<%@ page language="java" %>

There are three possible directives currently defined by the JSP specification: page, include, and taglib. Each one of these directives and their attributes, if applicable, are defined in the following sections.

  • The page Directive-
The page directive defines information that will be globally available for that JavaServer Page.

  • The include Directive-
The include directive is used to insert text and code at JSP translation time. The syntax of the include directive is as follows:

<%@ include file="relativeURLspec" %>

The file that the file attribute points to can reference a normal text HTML file or it can reference a JSP file, which will be evaluated at translation time.

  • The taglib Directive-
The most recent version of the JSP specification defines a mechanism for extending the current set of JSP tags. It does this by creating a custom set of tags called a tag library. That is what the taglib points to. The taglib directive declares that the page uses custom tags, uniquely names the tag library defining them, and associates a tag prefix that will distinguish usage of those tags. The syntax of the taglib directive is as follows:

<%@ taglib uri="tagLibraryURI" prefix="tagPrefix" %>


Scriptlet tag:
Scriptlets are what bring all the scripting elements together. They can contain any coding statements that are valid for the language referenced in the language directive. They are executed at request-time and they can make use of declarations, expressions, and JavaBeans. The syntax for a scriptlet is as follows:

<% scriptlet source %>

During the initial request the JSP scripting code is converted to servlet code and then compiled and loaded into resident memory. The actual source code, which is found between scriptlet tags <% ... %>, is placed into the newly created servlet's _jspService() method. See the following sample JSP source:

<% out.println("HELLO WORLD"); %>

It has a very simple scriptlet section that will print HELLO WORLD to the JspWriter implicit objectout.
You don't need to dig too deeply into the servlet code generated by the Web server, because it is generated for you. You just need to understand that it is being generated by the JSP engine and is the JSP equivalent to a servlet's service() method. It is also important to know that the JSP engine creates a servlet equivalent to the init() and destroy() methods.

Action tag:
Actions provide an abstraction that can be used to easily encapsulate common tasks. They typically create or act on objects, normally JavaBeans. The JSP technology provides some standard actions. These actions are defined in the following sections.

  • *jsp:useBean*
The *jsp:useBean* action associates an instance of a JavaBean defined with a given scope and ID, via a newly declared scripting variable of the same ID.

  • *jsp:setProperty*
The *jsp:setProperty* action sets the value of a bean's property.

  • *jsp:getProperty*
The *jsp:getProperty* action takes the value of the referenced bean instance's property, converts it to a java.lang.String, and places it into the implicit out object.

  • *jsp:include*
The *jsp:include* action provides a mechanism for including additional static and dynamic resources in the current JSP page. The syntax for this action is as follows:

*jsp:include page="urlSpec" flush="true" /*
and
*jsp:include page="urlSpec" flush="true"*
{ jsp:param ... /> }
*/jsp:include*

The first syntax example illustrates a request-time inclusion, whereas the second contains a list of param sub-elements that are used to argue the request for the purpose of inclusion.
N.B. Consider the stars as opening and closing angular brackets.

Thursday, 31 March 2011

J2ee: About JavaBean

Let me (JBS) provide you a simplest look at what a bean is. A JavaBean is a 100% Java component that works on any Java Virtual Machine.
The minimum requirements that make a component a JavaBean are as follows:
  1. It must support the JDK 1.1 and later Serialization model.
  2. It must use get/set accessors to expose its properties.
There is nothing magical about creating a JavaBean. You just create a Java class that implements the java.io.Serializable interface and uses public get/set methods to expose its properties.
The following listing provide you a simple JavaBean:

import java.io.Serializable;
public class SimpleJavaBean implements java.io.Serializable
{
private String simpleProperty = new String("");
public SimpleJavaBean() { }
public String getSimpleProperty()
{
return simpleProperty;
}
public void setSimpleProperty(String value)
{
simpleProperty = value;
}
}

This class is now a JavaBean. It satisfies the minimum requirements. You can now load the SimpleJavaBean into any JavaBeans–aware program that uses introspection and change its properties. Its state can then be saved and reloaded anytime, because of its support for serialization.
Let's take a look at an example that illustrates how to serialize our new bean. The second example on the next listing creates an instance of our SimpleJavaBean, sets the simpleProperty to "simple property value", serializes the bean to a file, reads the bean back in, and finally displays proof that its state was maintained.

import java.io.*;
public class SimpleJavaBeanTester
{
public SimpleJavaBeanTester() { }
public void storeBean(SimpleJavaBean value)
{
try
{
// Create the ObjectOutputStream passing it the
// FileOutputStream object that points to our
// persistent storage.
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("file.dat"));
// Write the SimpleJavaBean to the ObjectOutputStream
os.writeObject(value);
os.flush();
os.close();
}
catch (IOException ioe)
{
System.err.println(ioe.getMessage());
}
}
public SimpleJavaBean getBean()
{
SimpleJavaBean value = null;
try
{
// Create the ObjectInputStream passing it the FileInputStream object that points to our persistent storage.
ObjectInputStream is = new ObjectInputStream(new FileInputStream("file.dat"));
// Read the stored object and downcast it back to a SimpleJavaBean
value = (SimpleJavaBean)is.readObject();
is.close();
}
catch (IOException ioe)
{
System.err.println(ioe.getMessage());
}
catch (ClassNotFoundException cnfe)
{
System.err.println(cnfe.getMessage());
}
return value;
}
public void testBean()
{
// Create the Bean
SimpleJavaBean simpleBean = new SimpleJavaBean();
// Use accessor to set property
simpleBean.setSimpleProperty("simple property value");
// Serialize the Bean to a Persistent Store
storeBean(simpleBean);
// Get the Bean from the Persistent Store
SimpleJavaBean newBean = getBean();
System.out.println("The newBean's simpleProperty == " +newBean.getSimpleProperty());
}
public static void main(String[] args)
{
SimpleJavaBeanTester simpleJavaBeanTester = new SimpleJavaBeanTester();
simpleJavaBeanTester.testBean();
try
{
System.out.println("Press enter to continue...");
System.in.read();
}
catch (IOException ioe)
{
System.err.println(ioe.getMessage());
}
}
}

J2ee: The Life Cycle of a Servlet

The life cycle of a Java servlet is a very simple object-oriented design. A servlet is constructed and initialized. It then services zero or more requests until the service that it extends shuts down. At this point the servlet is destroyed and garbage collected. This design explains why servlets are such a good replacement for CGI. The servlet is loaded only once and it stays resident in memory while servicing requests.
The interface that declares this framework is the javax.servlet.Servlet interface. The Servlet interface defines the life cycle methods. These methods are init(), service(), and destroy(). But before the init() call, a without argument constructor is invoked.

init()
The init() method is where the servlet's life begins. It is called by the server immediately after the servlet is instantiated. It is called only once. In the init() method, the servlet creates and initializes any resources, including data members, that it will be using while handling requests. The init() method's signature is defined as follows:

  • public void init(ServletConfig config) throws ServletException;
The init() method takes a ServletConfig object as a parameter. You should save this object so that it can be referenced later. The most common way of doing this is to have the init() method call super.init(), passing it the ServletConfig object.
The init() method can throw a ServletException. If, for some reason, the servlet cannot initialize the resources necessary to handle requests, the init() method will throw a ServletException.

service()
The service() method handles all requests sent by a client. It cannot start servicing requests until the init() method has been executed. You will not usually implement this method directly, unless you extend the GenericServlet abstract class.
The most common implementation of the service() method is in the HttpServlet class. The HttpServlet class implements the Servlet interface by extending GenericServlet. Its service() method supports standard HTTP/1.1 requests by determining the request type and calling the appropriate method. The signature of the service() method is as follows:

  • public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
The service() method implements a request and response paradigm. The ServletRequest object contains information about the service request, encapsulating information provided by the client. The ServletResponse object contains the information returned to the client.

destroy()
This method signifies the end of a servlet's life. When a service is being shut down, it calls the servlet's destroy() method. This is where any resources that were created in the init() method will be cleaned up. If you have an open database connection, you should close it here. This is also a good place to save any persistent information that will be used the next time the servlet is loaded. The signature of the destroy() is as follows:

  • public void destroy();

Wednesday, 30 March 2011

DBMS: DK/NF (Domain/Key Normal Form)

Unlike previously defined normal forms, DK/NF is not defined in terms of traditional dependencies (functional, multivalued, or join). It was introduced by Ron Fagin in his paper "A Normal Form for Relational Databases that Is Based on Domains and Keys," ACM TODS 6, No. 3 (September 1981). Instead, it is defined in terms of the more primitive concepts of domain and key, along with the general concept of a “constraint.”
A domain constraint specifies the permissible values for a given attribute, while a key constraint specifies the attributes that uniquely identify a row in a given table. That is, A domain constraint--better called an attribute constraint--is simply a constraint to the effect a given attribute A of R takes its values from some given domain D. A key constraint is simply a constraint to the effect that a given set A, B, ..., C of R constitutes a key for R. To be specific, enforcing domain constraints just means checking that attribute values are always values from the applicable domain (i.e., values of the right type); enforcing key constraints just means checking that key values are unique.
By definition it is a normal form used in database normalization which requires that the database contains no constraints other than domain constraints and key constraints. That is, a relation schema is in DK/NF if every constraint can be inferred by simply knowing the set of attribute names and their underlying domains, along with the set of keys.
However, successfully building a domain/key normal form database remains a difficult task, even for experienced database programmers. Thus, while the domain/key normal form eliminates the problems found in most databases, it tends to be the most costly normal form to achieve. However, failing to achieve the domain/key normal form may carry long-term, hidden costs due to anomalies which appear in databases adhering only to lower normal forms over time. After transforming a database into DK/NF there would be no insertion or deletion anomalies.
The trouble is, lots of relvars aren't in DK/NF in the first place. For example, suppose there's a constraint on R to the effect that R must contain at least ten tuples. Then that constraint is certainly not a consequence of the domain and key constraints that apply to R, and so R isn't in DK/NF. The sad fact is, not all relvars can be reduced to DK/NF; nor do we know the answer to the question "Exactly when can a relvar be so reduced?".
Now, it's true that Fagin proves in his paper that if relvar R is in DK/NF, then R is automatically in 5NF (and hence 4NF, BCNF, etc.) as well. However, it's wrong to think of DK/NF as another step in the progression from 1NF to 2NF to ... to 5NF, because 5NF is always achievable, but DK/NF is not.
It's also wrong to say that there are "no normal forms higher than DK/NF." In CODD's recent work -- documented in the book TEMPORAL DATA AND THE RELATIONAL MODEL, he has come up with a new sixth normal form, 6NF. 6NF is higher than 5NF (all 6NF relvars are in 5NF, but the converse isn't true); moreover, 6NF is always achievable, but it isn't implied by DK/NF. In other words, there are relvars in DK/NF that aren't in 6NF.
Sometimes it is asked: "If a [relvar] has an atomic primary key and is in 3NF, is it automatically in DK/NF?" No. If the EMP relvar just shown is subject to the constraint that there must be at least ten employees, then EMP is in 3NF (and in fact 5NF) but not DK/NF.

For further study:

DBMS: Difference between a RELATION and a RELVAR

Sometimes it is difficult to determine the diferrence between a Relation and a Relvar. Both of them occurs in the question as synonyms. But I found them different. Here is a discussion on it...
In relational databases, a relvar is a term coined by C. J. Date as an abbreviation for the concept of relation variable, which is the actual term used by the inventor of the relational model, E. F. Codd, regarding the same concept. The term is used in Date's well-known database textbook "An Introduction to Database Systems" to differentiate between a variable that contains a relation and the relation itself.
Relvar is not universally accepted as a term, and it certainly has no meaning in the context of existing database management system products that support SQL. Other database textbooks use the term relation (or table) for both the variable and the data it contains. This is most likely because in SQL there are no variables, nor are there assignment operators.

For more information:
Click Here

Now I want to expand my thought with respect to the difference:
Let us consider a query in Oracle:
CREATE TABLE students (roll NUMBER(3), name VARCHAR2(30)) According to SQL standard it is a TABLE. But, look at the next statement in C Language.
int x=55;
it doesn't mean x 55, rather x is a variable and 55 is its value. Similarly "students" is a
relational variable (relvar) and it hols a relation (table). The SLQ INSERT statement actually insert a relation (table).

Wednesday, 23 March 2011

C Language: File Handling (Part 2)

Formatted Disk I/O Functions
For formatted reading and writing of character, string, integer, float, there exist two functions, fscanf( ) and fprintf( ). Their prototypes are as follows:

int fprintf(FILE *fp, const char *control_string,…);
int fscanf(FILE *fp, const char *control_string,…);
where fp is a file pointer returned by a call to fopen( ). fprintf( ) and fscanf( ) direct there I/O operations to the file pointed to by fp. There exist no standard library functions to read or write numbers under the category of unformatted, text I/O function.

EXM 06: Write a program to accept some records of students consisting their name, roll number, percentage of marks obtained and write them onto disk file in append mode. At last print all records of the file.

# include
# include
# include
# include

int main(void)
{
FILE *fp;
char name[25];
int roll;
float per;
fp=fopen("INFO.TXT", "a+");
if(!fp)
{
printf("\n File openning error");
exit(1);
}
printf("\n\t Now give records to insert:-\n");
do
{
printf("\n\n Give NAME(single word): ");
fflush(stdin);
gets(name);
printf("\n Give ROLL: ");
scanf("%d",&roll);
printf("\n Give PERCENTAGE: ");
scanf("%f",&per);
fprintf(fp,"%s %d %f\n",name,roll,per);
printf("\n\t Have more record(Y/N)? ");
}while(toupper(getche())!='N');
rewind(fp);
printf("\n\t Now view the records of the file:-\n");
while(fscanf(fp,"%s %d %f",name,&roll,&per)!=EOF)
/*Donot use while(!feof(fp))*/
printf("\n%s %d %.2f",name,roll,per);
return 0;
}

getw( ) and putw( )
These are two binary mode functions, so open the file in binary mode. This two functions are used for efficient use number manipulation in file, otherwise these these two functions are useless.
  1. int getw(FILE *stream); - getw( ) returns the next integer in the named input stream. It assumes no special alignment in the file. getw( ) should not be used when the stream is opened in text mode.
  2. int putw(int w, FILE *stream); - putw( ) outputs the integer w to the given stream. It does not expect (and does not cause) special alignment in the file.

Return Value:
On success,
getw( ) returns the next integer on the input stream.
putw( ) returns the integer w.
On error,
getw( ) returns EOF
putw( ) returns EOF
On end-of-file, getw( ) returns EOF

Because EOF is a legitimate value for getw( ) to return, use feof( ) to detect end-of-file or ferror( ) to detect error. Because EOF is a legitimate integer, use ferror( ) to detect errors with putw( ).

EXM 07: Write a program to accept some integers and store them in a file using putw() function and then read the file. Use getw() function to read the specified file.

# include
# include
# include

int main(void)
{
FILE *fp;
char fln[15];
int x;
printf("\n Give the file name: ");
scanf("%s", fln);
fp=fopen(fln, "wb+");
if( !fp )
{
printf("\n File opening error");
exit(1);
}
do
{
printf("\n Give the number: ");
scanf("%d", &x);
putw(x, fp);
printf("\n\t Want to continue(Y/N)? ");
}while(toupper(getche())!='N');
rewind(fp);
printf("\n The integer content of the file:-\n");
while((x=getw(fp))!=EOF)
printf(" %d", x);
fclose(fp);
return 0;
}

EXM 08: Suppose there is a file by the name of INTEGERS.TXT containing integers. Write a program to transfer all odd and even integers from that file into the ODD.TXT and EVEN.TXT files respectively.

# include
# include

void main(void)
{
FILE *fs, *fe, *fo;
int x;
fs=fopen("INTEGERS.TXT","rb");
fe=fopen("EVEN.TXT","wb");
fo=fopen("ODD.TXT","wb");
if(!fs||!fe||!fo)
{
printf("\n File opening error");
exit(1);
}
while((x=getw(fs))!=EOF)
{
if(x%2==0)
putw(x,fe);
else
putw(x,fo);
}
printf("\n File manipulation complete .....");
fcloseall();
}


Text Vs. Binary Mode
As yet we have dealt with TEXT mode, but there exists another mode called BINARY mode to deal with file opening. There are three main areas where text and binary mode files are different:

  1. The handling of newlines: In text mode, a newline character is 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 newline when a C program reads the file. But, if a file is opened in binary mode, as opposed to text mode, these conversions will not take place. As a result, a character count program, where the file is opened in text mode, shows less number of characters than if the file would have been opened in binary mode. The binary mode value is exactly same as that reported by the DIR command.
  2. The representation of end of file: In text mode, a special character (EOF), whose ASCII value is 26, is inserted after the last character in the file to mark the end of file. In binary mode no such special character is used to mark the end of file. The binary mode files keep track of the end of file from the number of characters present in the directory entry of the file. Due to this difference, if a file stores numbers in binary mode, it is important that binary mode only be used for reading the number back, since one of the numbers we stored might be the number 26. If this number is detected while we are reading the file by opening it in text mode, reading would be terminated before actual termination of the file. Hence, two modes are not compatible.
  3. The storage of numbers: The only function that is available for storing numbers in a disk file is the fprintf( ) function. If we use this function then, text and characters are stored one character per byte. But the numbers are not stored as they are in memory (two bytes for an integer, four bytes for an float, and so on). Numbers are stored as string of characters. Thus, 1234, even though it occupies two bytes in memory, when transferred to the disk using fprintf( ),it would occupy four bytes, one byte per character. Similarly, the floating-point number 1234.56 would occupy 7 bytes on disk. On the other hand if the file is opened in binary and use those functions that store the number in binary format, each number would occupy same number of bytes on disk as it occupies in memory.

Functions for Binary File I/O
  • fread( )

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

** Remarks: fread reads a specified number of equal-sized data items from an input stream into a block.

** Argument | What It Is/Does
-----------------------------------------------------
ptr | Points to a block into which data is read
size | Length of each item read, in bytes
n | Number of items read
stream | Points to input stream

** The total number of bytes read is (n * size).

** Return Value: On success, fread returns the number of items (not bytes) actually read. On end-of-file or error, fread returns a short count (possibly 0).

  • fwrite( )

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

** Remarks: fwrite appends a specified number of equal-sized data items to an output file.
** Argument | What It Is/Does
-------------------------------------
ptr | Pointer to any object; the data written begins at ptr
size | Length of each item of data
n | Number of data items to be appended
stream | Specifies output file

** The total number of bytes written is (n * size)

** Return Value: On success, returns the number of items (not bytes) actually written. On error, returns a short count.

  • ftell( )

** Returns the current file pointer

** Declaration:
long ftell(FILE *stream);

** Remarks: ftell returns the current file pointer for stream. If the file is binary, the offset is measured in bytes from the beginning of the file. The value returned by ftell can be used in a subsequent call to fseek.

** Return Value: On success, returns the current file pointer position. On error, returns -1L and sets errno to a positive value.

  • fseek( )

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

** Remarks: fseek sets the file pointer associated with a stream to a new position.

** Argument | What It Is/Does
------------------------------------------------------------------------
stream | Stream whose file pointer fseek sets
offset | Difference in bytes between whence (a file pointer position)
and new position. For text mode streams, offset should be 0 or
a value returned by ftell.
whence | One of three SEEK_xxx file pointer locations (0, 1, or 2)

** Return Value: On success (the pointer is successfully moved), fseek returns 0. On failure, fseek returns a non-zero value. fseek returns an error code only on an unopened file or device.

  • SEEK_xxx

** Constant | Value | File location
----------------------------------------------------
SEEK_SET | 0 | Seeks from beginning of file
SEEK_CUR | 1 | Seeks from current position
SEEK_END | 2 | Seeks from end of file

EXM 09: Write a program to create a file containing information of employees such as there name, designation, total salary, etc. Insert some employees' details onto the file using fwrite( ) and finally print these information in tabular form using fread( ) function.

# include
# include
# include
# include
# include

struct employee
{
char name[30];
float sal;
};
typedef struct employee EMP;

void main (void)
{
EMP a;
FILE *fp;
double dummy=sin(0.0);
dummy++;
clrscr();
fp=fopen("EMP.BIN", "wb+");
if(!fp)
{
printf("\n File opening error!!");
exit(1);
}
printf("\n Give info. of employees:-");
do
{
printf("\n\n Give NAME: ");
fflush( stdin );
fgets(a.name, 30,stdin);
printf("\n Give SALARY: ");
scanf("%f", &a.sal);
fwrite( &a, sizeof(a), 1, fp );
printf("\n Have more (Y/N)? ");
} while( toupper(getche()) != 'N' );
rewind(fp);
printf("\n\n Information of the employees in the file:-");
while( fread(&a, sizeof(a), 1, fp) == 1 )
{
a.name[strlen(a.name)-1]='\0';
printf("\n %s %.2f", a.name, a.sal);
}
getch();
fclose(fp);
}

If you have any problem email me: jayanta4u2006@gmail.com

Tuesday, 22 March 2011

C Language: File Handling (Part 1)

File Handling in C-language

Streams and Files
The C I/O system supplies a consistent interface to the programmer independent of the actual device being accessed. That is, the C I/O system provides a level of abstraction between the programmer and the device. This abstraction is called a stream and the actual device is called a file.

Streams
The C file system is designed to work with a wide variety of devices, including terminals, disk drives, and tape drives. Even though each device is very different, the buffered file system transform each into a logical device called stream. All streams behave similarly. Because streams are largely device independent, the same function that can write to a disk file can also be used to write ton another type of device, such as the console.
There are two types of streams as follows:

1) Text stream: A text stream is a sequence of characters. Standard C allows (but not required) a text stream to be organized into lines terminated by a newline character. However, the newline character is optional on the last line. In a text stream, certain character translations may occur as required by the host environment. For example, a newline may be converted to a carriage return/linefeed pair. Therefore there may not be a one-to-one relationship between the character that are written (or read) and those on the external device.

2) Binary stream: A binary stream is a sequence of bytes that have a one-to-one correspondence to those in the external device-that is, no character translation occur. Also, the number bytes written (or read) are the same as the number on the external device.

Files
In C/C++, a file may be anything from a disk file to a terminal or printer. You associate a stream with a specific file by performing an open operation. Once a file is open, information may be exchanged between it and your program. Here we have to remember all streams are same but all files are not.
You disassociate a file from a specific stream with a close operation. If you close a file opened for output, the contents, if any, of its associated stream are written to the external device. This process is generally referred to as flushing the stream, and guarantees that no information is accidentally left in the disk buffer. All files are closed automatically when your program terminates normally. But files are not closed when a program terminates abnormally.
Each stream is associated with a file, has a file control structure of type FILE.

The File Pointer
A file pointer is a pointer to a structure of type FILE. It points to information that defines various things about the file, including its name, status, and the current position of the file. To obtain a file pointer variable, use a statement like this:

FILE *fp;

Opening a File
The fopen( ) function opens stream for use and link a file with that stream. Then it returns the file pointer associated with the file. The fopen( ) function has the following prototype:

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

where filename is a pointer to a string of characters that makeup a valid filename and may include a path specification. The string pointed to by mode determines how the file will be opened. The following table shows the legal values for mode.

Mode

Meaning

r

Open a text file for reading.

w

Create a text file for writing.

a

Append to a text file.

rb

Open a binary file for reading

wb

Create a binary file for writing.

ab

Append to a binary file.

r+

Open a text file for read/write.

w+

Create a text file for read/write.

a+

Append or create a text file for read/write.

r+b / rb+

Open a binary file for read/write.

w+b / wb+

Create a binary file for read/write.

a+b / ab+

Append or create a binary file for read/write.


If, when opening a file for read only operation, the file does not exist, fopen( ) will fail. When opening a file using append mode, if the file does not exist, it will be created. Further, when a file is opened for append, all new data written to the file will be written to the end of the file. The original content will remain unchanged. When a file is opened for writing, the file does not exist, it will be created. If it does exist, the content of the original file will be destroyed and a new file created. The difference between the mode r+ and w+ is that r+ will not create a file if it does not exist; however, w+ will. Further, if the file already exists, opening it with w+ destroys its contents; opening with r+ does not.
The number of files that may be open at any one time is specified by FOPEN_MAX. this value will usually be at least 8.

Closing a File
The fclose( ) function closes the stream that was opened by a call to fopen( ). It writes any data still remaining in the disk buffer to the file and does a formal operating-system-level close on the file. Failure to close a stream invites all kind of trouble, including lost data, destroyed file, and possible intermittent error in your program. fclose( ) also frees the file control block associated with the stream, making it available for reuse. The prototype for fclose( ) function is as follows;

int fclose(FILE *fp);

where fp is the file pointer returned by the call to fopen( ). A return value of zero signifies a successful close operation. The function returns EOF if an error occurs.
There is another function fcloseall( ) which requires no argument and closes all open file at a time.

EXM 01: Write a program to check whether a file is present or not in the disk.

# include
# include

int main(void)
{
char fln[20];
FILE *fp;
clrscr();
printf("\n Give the name of the file: ");
scanf(“%s”, fln);
fp=fopen(fln,"r");
if(fp)
printf("\n The file %s is persent in the current directory",fln);
else
printf("\n The file %s is not persent in the current directory",fln);
fclose(fp);
return 0;
}

Reading and Writing a Character
There are two identical way to output a character: putc( ) (macro) and fputc( ). Prototype of putc( ):
int putc(int ch, FILE *fp);

where fp is a file pointer returned by fopen( ) and ch is the character to be output. If a putc( ) operation is successful, it returns the character written. Otherwise, it returns EOF.
Similarly there are two equivalent functions that input a character: getc( ) and fgetc( ). The prototype of getc( ):

int getc(FILE *fp);

getc( ) returns an integer, but the character is contained in the low-order byte. Unless an error occurs, the high-order byte is zero. getc( ) function returns an EOF when the end-of –file has been reached or if an error occur.

EXM 02: Write a program to create a file.

# include
# include

int main(void)
{
FILE *fp;
char fln[20],ch;
printf("\n Give the file name to create: ");
scanf("%s", fln);
fp=fopen(fln,"w");
if(!fp)
{
printf("\n File opening error...");
exit(1);
}
printf("\n Now type its content & press (ctrl+z) to terminate the file:-\n");
while((ch=getche())!=26)
putc(ch,fp);
printf("\n One file copied...");
fclose(fp);
return 0;
}

EXM 03: Write a program to read a file.

# include
# include
# include

int main(void)
{
char fln[20],ch;
FILE *fp;
clrscr();
printf("\n Give the file name to be read: ");
scanf("%s", fln);
fp=fopen(fln,"r");
if(!fp)
{
printf("\n The file cannot be opened");
exit(1);
}
printf("\n The content of the file %s :-\n ",fln);
while((ch=getc(fp))!=EOF)
putchar(ch);
getch();
return 0;
}

Using feof( )
There is a problem to deal with EOF using getc( ) function, if a file is opened for binary input, an integer value that will test equal to EOF may be read. This would cause the input routine to indicate an end-of –file condition even though the physical end of the file had not been reached. On the other hand as getc( ) returns EOF when it fails and when it reaches the end of the file. Using only the return value of getc( ), it is impossible to know which occurred. This problem can be solved by using feof( ) function, which determines when the end of file has been encountered. The feof( ) function has the following prototype:

int feof(FILE *fp);

feof( ) returns true if the end of the file has been reached; otherwise it returns zero.

EXM 04: Write a file copy program using command line argument.

# include
# include

int main(int argc, char *argv[]){
char ch;
FILE *fps, *fpt;
if(argc != 3){
printf("\n Invalid number argument......");
exit(0);
}
fps=fopen(argv[1], "r");
fpt=fopen(argv[2], "w");
if( !fps || !fpt ){
printf("\n File openning error......");
exit(0);
}
while( !feof(fps) ){
ch=getc( fps );
putc(ch, fpt);
}
printf("\n One file copied......");
return 0;
}

Try yourself:

Problem 01: Suppose a text file contains so many characters in both lower case and upper case. Now create another file where all these characters of the first one are present but all characters are in upper case. Write a program to perform the above-mentioned task.

Problem 02: Write "C" program to count the number of words in a file. Assume that a word is a sequence of letters ending with a blank, or a tab or a end of line marker or end of file or punctuation symbols such as ",", ".", "!" and "?".

fputs( ) and fgets( )
fgets( ) and fputs( ) functions read and write character strings from and to a disk file. They have the following prototypes:

int fputs(const char *str, FILE *fp);
char *fgets(char *str, int length, FILE *fp);

fputs( ) function returns EOF if an error occurs. Here in the program given below gets( ) does not store the newline character, hence a newline should be added before each string is written to the file so that the file can be read more easily.
The fgets( ) function read a string from the specified stream until either a newline character is read or length-1 character has been read. If a newline is read, it will be part of the string (unlike the gets( ) function) . The resultant string will be null terminated. The function returns str if successful and a null pointer if an error occurs.

rewind( )
The rewind( ) function resets the file position indicator to the beginning of the file specified as its argument. It has the following prototype:

void rewind(FILE *fp);

EXM 05: Write a program to accept strings from keyboard & write them to the file. At last read the accepted strings from the file & display them on the screen.

# include
# include
# include

int main(void)
{
FILE *fp;
char fln[15], str[80];
printf("\n Give the file name: ");
scanf("%s", fln);
fp=fopen(fln,"w+");
if(!fp)
{
printf("\n File opening error");
exit(1);
}
printf("\n Enter few lines of texts & press twice to terminate:-\n");
do
{
fflush(stdin);
gets(str);
strcat(str,"\n");
fputs(str,fp);
}while(str[0]!='\n');
printf("\n\t 1 File(s) copied");
printf("\n\n View the written content of the file...\n");
rewind(fp);
while(!feof(fp))
{
fgets(str,79,fp);
printf(str);
}
fclose(fp);
return 0;
}

End of Part 1 to be continued on part 2...