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...

Monday, 21 March 2011

Core Java: Thread Intro & Lifecycle


THREADING

A multithreaded program contains two or more parts that can run concurrently. Each part of such a program is called a thread and each thread defines a separate path of execution. Thus, multithreading is a specialization form of multi tasking.
There are two distinct types of multitasking: process-based and thread-based. A process is a program that is executing. Thus, process-based multitasking is the feature that allows your computer to run two or more programs concurrently. For example, process based multitasking enables us to run MS-word for editing a word document at the same time running media player to listen some sweet music. In processed based multitasking a program is the smallest unit of code that can be dispatched by a scheduler. (A process migrates between the various scheduling queues throughout its lifetime. The operating system must select, for scheduling purposes, processes from these queues in some fashion. The appropriate scheduler carries out the selection process).
On the other hand in thread-based multitasking system, the thread is the smallest unit of dispatch able code. That is, a single program can perform two or more tasks simultaneously. For instance, a user can simultaneously type in characters and run the spell checker within the same process.
A thread, sometimes called a lightweight process (LWP), because the threads share the common memory space. The memory allocated to the main thread will be shared by all other child threads. Whereas in case of Process the child process are in need to allocate the seperate memory space.
It is a basic unit of CPU utilization; it comprises a thre
ad ID, a program counter, a register set, and a stack. It shares with other threads belonging to the same process its code section, data section, and other operating system resources, such as open files and signals. A traditional (or heavyweight) process has a single thread of control. If the process has multiple threads of control, it can do more than one task at a time. Hence a multitasking thread requires fewer overheads than multitasking processes.

LIFE CYCLE OF A THREAD

During the lifetime of a thread, there are many states it can enter. They include:
  1. Newborn state
  2. Runnable state
  3. Running state
  4. Blocking state
  5. Dead state
A thread is always in one of these five states. It can move from one state to another
via a variety of ways as shown in the following figure:
Newborn State:
When we create a thread object, the thread is born and is said to be in newborn state. The thread is not yet scheduled for running. At this state, we can do only one of the following things with it:
Schedule it for running using start( ) method.
Kill it by using stop( )
If scheduled, it moves to the Runnable state. If we attempt to use any other method at this stage, an exception will be thrown.

Runnable State:
The runnable state means that the thread is ready for execution and is waiting for execution and i.e. for the availability of the processor. That is, the thread has joined the queue of threads that are waiting for execution. Java assigns each thread a priority (an integer) that determines how that thread should be treated with respect to the others. A thread priority is used to decide when to switch from one running thread to the next. This is called context switch. The rule that determine when a context switch takes place are simple:
A thread can voluntarily give up control.
A higher-priority thread can preempt a thread.
In case of threads whit equal priority, some OS’ like Win-98 allocate time-slice automatically for them in round-robin (US tournament in which each competitor plays every other.) fashion. On some other OS’, threads of equal priority must voluntarily yield control to other thread with equal priority. However, if we want a thread to give up control to another thread of equal priority before its turn comes, we can do so by using the yield( ) method.

Running State:
Running means that the processor has given its time to the thread for its execution. The thread runs until it relinquish (v. to give sth. up) control on its own or it is preempted (v. to prevent sth. happening by taking action to stop it) by a higher priority thread. A running thread may relinquish its control in one of the following situation.
  1. It has been suspended using suspend( ) method. A suspended thread can be revived by using the resume( ) method. This approach is useful when we want to suspend a thread for some time due to certain reason, but do not want to kill it.
  2. It has been made to sleep. We can put a thread to sleep for a specified time period using the method sleep( time ) where time is in milliseconds. This is that the thread is out of queue during this period. The thread re-enters the runnable state as soon as this time period is elapsed.
  3. It has been told to wait until some event occurs. This is done using the wait( ) method. The thread can be scheduled to run again using the notify( ) method.
Blocking State:
A thread is said to be blocked when it is prevented from entering into the runnable state and subsequently the running state. This happens when the thread is suspended, sleeping, or waiting in order to satisfy certain requirements. A blocked thread is considered “not runnable” but not dead there fully qualified to run again.

Dead State:
Every thread has a life cycle. A running thread ends its life when it has completed executing its run( ) method. It is a natural dead. However, we can kill it by sending to stop message to it at any state thus causing a premature death to it. A thread can be killed as soon it is born, or while it is running, or even when it is in “not runnable” (blocked) condition.


Sunday, 20 March 2011

J2ee: HTTP Basics

Requests, Responses, and Headers

HTTP is a simple, stateless protocol. A client, such as a web browser, makes a request, the web server responds, and the transaction is done. When the client sends a request, the first thing it specifies is an HTTP command, called a method, that tells the server the type of action it wants performed. This first line of the request also specifies the address of a document (a URL) and the version of the HTTP protocol it is using. For example:

GET /intro.html HTTP/1.0

This request uses the GET method to ask for the document named intro.html, using HTTP Version 1.0. After sending the request, the client can send optional header information to tell the server extra information about the request, such as what software the client is running and what content types it understands. This information doesn’t directly pertain to what was requested, but it could be used by the server in generating its response. Here are some sample request headers:

User-Agent: Mozilla/4.0 (compatible; MSIE 4.0; Windows 95)
Accept: image/gif, image/jpeg, text/*, */*

The User-Agent header provides information about the client software, while the Accept header specifies the media (MIME) types that the client prefers to accept.

After the headers, the client sends a blank line, to indicate the end of the header section. The client can also send additional data, if appropriate for the method being used, as it is with the POST method. If the request doesn’t send any data, it ends with an empty line.

After the client sends the request, the server processes it and sends back a response. The first line of the response is a status line that specifies the version of the HTTP protocol the server is using, a status code, and a description of the status code. For example:

HTTP/1.0 200 OK

This status line includes a status code of 200, which indicates that the request was successful, hence the description “OK”. Another common status code is 404, with the description “Not Found”—as you can guess, this means that the requested document was not found.

After the status line, the server sends response headers that tell the client things like what software the server is running and the content type of the server’s response. For example:

Date: Saturday, 23-May-98 03:25:12 GMT
Server: JavaWebServer/1.1.1
MIME-version: 1.0
Content-type: text/html
Content-length: 1029
Last-modified: Thursday, 7-May-98 12:15:35 GMT

The Server header provides information about the server software, while the Content-type header specifies the MIME type of the data included with the response. The server sends a blank line after the headers, to conclude the header section. If the request was successful, the requested data is then sent as part of the response. Otherwise, the response may contain human-readable data that explains why the server couldn’t fulfill the request.


GET and POST

When a client connects to a server and makes an HTTP request, the request can be of several different types, called methods. The most frequently used methods are GET and POST. Put simply, the GET method is designed for getting information (a document, a chart, or the results from a database query), while the POST method is designed for posting information (a credit card number, some new chart data, or information that is to be stored in a database).

The GET method, although it’s designed for reading information, can include as part of the request some of its own information that better describes what to get — such as an x, y scale for a dynamically created chart. This information is passed as a sequence of characters appended to the request URL in what’s called a query string. Placing the extra information in the URL in this way allows the page to be book marked or emailed like any other. Because GET requests theoretically shouldn’t need to send large amounts of information, some servers limit the length of URLs and query strings to about 240 characters.

The POST method uses a different technique to send information to the server because in some cases it may need to send megabytes of information. A POST request passes all its data, of unlimited length, directly over the socket connection as part of its HTTP request body. The exchange is invisible to the client. The URL doesn’t change at all. Consequently, POST requests cannot be bookmarked or emailed. In practice, the use of GET and POST has strayed from the original intent. It’s common for long parameterized requests for information to use POST instead of GET to work around problems with overly long URLs. Just remember that GET requests, because they can be bookmarked so easily, should not be allowed to cause damage for which the client could be held responsible. In other words, GET requests should not be used to place an order, update a database, or take an explicit client action in any way.


Other Methods

In addition to GET and POST, there are several other lesser-used HTTP methods. There’s the HEAD method, which is sent by a client when it wants to see only the headers of the response, to determine the document’s size, modification time, or general availability. There’s also PUT, to place documents directly on the server, and DELETE, to do just the opposite. These last two aren’t widely supported due to complicated policy issues. The TRACE method is used as a debugging aid—it returns to the client the exact contents of its request. Finally, the OPTIONS method can be used to ask the server which methods it supports or what options are available for a particular resource on the server.